我有一个绿色和红色线条和透明背景的png图像,我需要使用它作为执行GrabCut的掩码。但我得到意想不到的结果。这是我的代码:
//find the mask
Mat mask;
mask.create( image.size(), CV_8UC1);
mask.setTo(Scalar::all(GC_BGD));
Mat maskImg = imread("messi5.png");
for(int i=0; i<maskImg.cols; i++)
for(int j=0; j<maskImg.rows; j++)
{
//if it's red, make it white
if ((int)maskImg.at<cv::Vec3b>(j,i)[0]==0 && (int)maskImg.at<cv::Vec3b>(j,i)[1] == 0 && (int)maskImg.at<cv::Vec3b>(j,i)[2] == 255) {
mask.at<cv::Vec3b>(j,i)[0]= GC_BGD;
mask.at<cv::Vec3b>(j,i)[1] = GC_BGD;
mask.at<cv::Vec3b>(j,i)[2] = GC_BGD;
}
//if it's green, make it black
if ((int)maskImg.at<cv::Vec3b>(j,i)[0]==0 && (int)maskImg.at<cv::Vec3b>(j,i)[1] == 255 && (int)maskImg.at<cv::Vec3b>(j,i)[2] == 0) {
mask.at<cv::Vec3b>(j,i)[0] = GC_FGD;
mask.at<cv::Vec3b>(j,i)[1] = GC_FGD;
mask.at<cv::Vec3b>(j,i)[2] = GC_FGD;
}
}
...
这是输出:http://prntscr.com/40kt4e。我猜它没有矩形,它只能看到GC_FGD像素,其他一切都被认为是BG。它看起来有点缩放,但我不知道如何解决它。
答案 0 :(得分:1)
我试图在
中说GrabCut reading mask from PNG file in OpenCV (C++)
您使用3通道访问器获取1通道图像。这会弄乱一些东西,使用1通道版本作为1通道掩码:
Mat image;
image= cv::imread(file);
//everything outside this box will be set to def.
//background GC_BGD, clearly from the image you can see that the players legs are outside the box,
//so this will cause problems. you need to either change the box,
//such that everything is outside the box is the background, or use your mask to scribble on the players legs in green.
cv::Rect rectangle(startX, startY, width, height);
cv::Mat bgModel,fgModel;
//find the mask
Mat mask;
mask.create( image.size(), CV_8UC1); //CV_8UC1 is single channel
mask.setTo(Scalar::all(GC_BGD)); //you have set it to all def. background
Mat maskImg = imread("messi5.png");
for(int i=0; i<maskImg.cols; i++)
for(int j=0; j<maskImg.rows; j++)
{
//if it's red, make it black
if ((int)maskImg.at<cv::Vec3b>(j,i)[0]==0 && (int)maskImg.at<cv::Vec3b>(j,i)[1] == 0 && (int)maskImg.at<cv::Vec3b>(j,i)[2] == 255) {
//the whole mask is black so this is redundant
mask.at<uchar>(j,i)= GC_BGD; //GC_BGD := 0 := black
}
//if it's green, make it white
if ((int)maskImg.at<cv::Vec3b>(j,i)[0]==0 && (int)maskImg.at<cv::Vec3b>(j,i)[1] == 255 && (int)maskImg.at<cv::Vec3b>(j,i)[2] == 0) {
mask.at<uchar>(j,i) = GC_FGD; //GC_FGD:= 1 := white
}
}
有关循环图像的更有效代码,请参阅: http://docs.opencv.org/doc/tutorials/core/how_to_scan_images/how_to_scan_images.html
LUT功能我在这里诀窍: http://docs.opencv.org/doc/tutorials/core/how_to_scan_images/how_to_scan_images.html#the-core-function