OpenCV GrabCut 蒙版
OpenCV GrabCut Mask
我已经利用 OpenCV GrabCut 功能执行图像分割。当按照下面的代码查看分割后的图像时,分割为reasonable/correct。但是,在查看(尝试使用)分段掩码值时,我得到了一些非常大的数字,而不是人们期望从 cv::GrabCutClasses
枚举中得到的枚举值。
void doGrabCut(){
Vector2i imgDims = getImageDims();
//Wite image to OpenCV Mat.
const Vector4u *rgb = getRGB();
cv::Mat rgbMat(imgDims.height, imgDims.width, CV_8UC3);
for (int i = 0; i < imgDims.height; i++) {
for (int j = 0; j < imgDims.width; j++) {
int idx = i * imgDims.width + j;
rgbMat.ptr<cv::Vec3b>(i)[j][2] = rgb[idx].x;
rgbMat.ptr<cv::Vec3b>(i)[j][1] = rgb[idx].y;
rgbMat.ptr<cv::Vec3b>(i)[j][0] = rgb[idx].z;
}
}
//Do graph cut.
cv::Mat res, fgModel, bgModel;
cv::Rect bb(bb_begin.x, bb_begin.y, bb_end.x - bb_begin.x, bb_end.y - bb_begin.y);
cv::grabCut(rgbMat, res, bb, bgModel, fgModel, 10, cv::GC_INIT_WITH_RECT);
cv::compare(res, cv::GC_PR_FGD, res, cv::CMP_EQ);
//Write mask.
Vector4u *maskPtr = getMask();//uchar
for (int i = 0; i < imgDims.height; i++) {
for (int j = 0; j < imgDims.width; j++) {
cv::GrabCutClasses classification = res.at<cv::GrabCutClasses>(i, j);
int idx = i * imgDims.width + j;
std::cout << classification << std::endl;//Strange numbers here.
maskPtr[idx].x = (classification == cv::GC_PR_FGD) ? 255 : 0;//This always evaluates to 0.
}
}
cv::Mat foreground(rgbMat.size(), CV_8UC3, cv::Scalar(255, 255, 255));
rgbMat.copyTo(foreground, res);
cv::imshow("GC Output", foreground);
}
当分割定性正确时,为什么会得到枚举之外的数字?
我怀疑你的//Write mask.
步骤,你为什么要重新迭代res
并将maskPtr
修改为maskPtr[idx].x = (classification == cv::GC_PR_FGD) ? 255 : 0;
,基本上你已经有了单通道二进制图像存储在res
变量中,cv::compare()
returns二值图像
但是,如果您仍想通过迭代来调试这些值,那么您应该使用标准技术来迭代单通道图像,如:
for (int i = 0; i < m.rows; i++) {
for (int j = 0; j < m.cols; j++) {
uchar classification = res.at<uchar>(i, j);
std::cout << int(classification) << ", ";
}
}
当您迭代单通道垫时,您必须使用 res.at<uchar>(i, j)
而不是 res.at<cv::GrabCutClasses>
。
我已经利用 OpenCV GrabCut 功能执行图像分割。当按照下面的代码查看分割后的图像时,分割为reasonable/correct。但是,在查看(尝试使用)分段掩码值时,我得到了一些非常大的数字,而不是人们期望从 cv::GrabCutClasses
枚举中得到的枚举值。
void doGrabCut(){
Vector2i imgDims = getImageDims();
//Wite image to OpenCV Mat.
const Vector4u *rgb = getRGB();
cv::Mat rgbMat(imgDims.height, imgDims.width, CV_8UC3);
for (int i = 0; i < imgDims.height; i++) {
for (int j = 0; j < imgDims.width; j++) {
int idx = i * imgDims.width + j;
rgbMat.ptr<cv::Vec3b>(i)[j][2] = rgb[idx].x;
rgbMat.ptr<cv::Vec3b>(i)[j][1] = rgb[idx].y;
rgbMat.ptr<cv::Vec3b>(i)[j][0] = rgb[idx].z;
}
}
//Do graph cut.
cv::Mat res, fgModel, bgModel;
cv::Rect bb(bb_begin.x, bb_begin.y, bb_end.x - bb_begin.x, bb_end.y - bb_begin.y);
cv::grabCut(rgbMat, res, bb, bgModel, fgModel, 10, cv::GC_INIT_WITH_RECT);
cv::compare(res, cv::GC_PR_FGD, res, cv::CMP_EQ);
//Write mask.
Vector4u *maskPtr = getMask();//uchar
for (int i = 0; i < imgDims.height; i++) {
for (int j = 0; j < imgDims.width; j++) {
cv::GrabCutClasses classification = res.at<cv::GrabCutClasses>(i, j);
int idx = i * imgDims.width + j;
std::cout << classification << std::endl;//Strange numbers here.
maskPtr[idx].x = (classification == cv::GC_PR_FGD) ? 255 : 0;//This always evaluates to 0.
}
}
cv::Mat foreground(rgbMat.size(), CV_8UC3, cv::Scalar(255, 255, 255));
rgbMat.copyTo(foreground, res);
cv::imshow("GC Output", foreground);
}
当分割定性正确时,为什么会得到枚举之外的数字?
我怀疑你的//Write mask.
步骤,你为什么要重新迭代res
并将maskPtr
修改为maskPtr[idx].x = (classification == cv::GC_PR_FGD) ? 255 : 0;
,基本上你已经有了单通道二进制图像存储在res
变量中,cv::compare()
returns二值图像
但是,如果您仍想通过迭代来调试这些值,那么您应该使用标准技术来迭代单通道图像,如:
for (int i = 0; i < m.rows; i++) {
for (int j = 0; j < m.cols; j++) {
uchar classification = res.at<uchar>(i, j);
std::cout << int(classification) << ", ";
}
}
当您迭代单通道垫时,您必须使用 res.at<uchar>(i, j)
而不是 res.at<cv::GrabCutClasses>
。