在iOS上使用触摸事件作为OpenCV分水线算法的标记
问题描述:
我试图在OpenCV网站上复制this sample在iOS应用上。在iOS上使用触摸事件作为OpenCV分水线算法的标记
问题是setMouseCallback
从High-level GUI
在逻辑上不适用于像iOS这样的移动平台。
所以我所做的是让用户可以在图像上方绘制图像,然后将图形和图像传递给我的OpenCV处理函数。
经过各种尝试,似乎我的绘图不被认为是一个标记掩码,所以我可能在某个地方犯了一个错误,而我真的不知道使用绘图参数。
我的代码:
- (UIImage *)watershedMAN:(UIImage *)imageRaw markers:(UIImage *)drawing {
Mat img, imgGray, markerMask, maskerMaskDrawn;
UIImageToMat(imageRaw, img);
UIImageToMat(drawing, maskerMaskDrawn);
cvtColor(img, markerMask, COLOR_BGR2GRAY);
cvtColor(markerMask, imgGray, COLOR_GRAY2BGR);
markerMask = Scalar::all(0);
//
// How to use 'maskerMaskDrawn' here?
//
int i, j, compCount = 0;
vector<vector<cv::Point> > contours;
vector<Vec4i> hierarchy;
findContours(markerMask, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
Mat markers(markerMask.size(), CV_32S);
markers = Scalar::all(0);
int idx = 0;
for(; idx >= 0; idx = hierarchy[idx][0], compCount++)
{
drawContours(markers, contours, idx, Scalar::all(compCount+1), -1, 8, hierarchy, INT_MAX);
}
vector<Vec3b> colorTab;
for(i = 0; i < compCount; i++)
{
int b = theRNG().uniform(0, 255);
int g = theRNG().uniform(0, 255);
int r = theRNG().uniform(0, 255);
colorTab.push_back(Vec3b((uchar)b, (uchar)g, (uchar)r));
}
watershed(img, markers);
Mat wshed(markers.size(), CV_8UC3);
for(i = 0; i < markers.rows; i++)
for(j = 0; j < markers.cols; j++)
{
int index = markers.at<int>(i,j);
if(index == -1)
wshed.at<Vec3b>(i,j) = Vec3b(255,255,255);
else if(index <= 0 || index > compCount)
wshed.at<Vec3b>(i,j) = Vec3b(0,0,0);
else
wshed.at<Vec3b>(i,j) = colorTab[index - 1];
}
wshed = wshed*0.5 + imgGray*0.5;
return MatToUIImage(wshed);
}
imageRaw and drawing arguments
THX。
答
问题已解决。
首先,UIImage色彩空间必须从BRGA转换为BGR。 然后,我的绘图背景很清晰,所以我必须使用void UIImageToMat(const UIImage* image, cv::Mat& m, bool alphaExist = false);
并将alphaExist
设置为true。
这是我的工作代码:
- (UIImage *)watershedMAN:(UIImage *)imageRaw drawing:(UIImage *)drawingRaw {
Mat img0, img, imgGray, wshed, drawingMask;
UIImageToMat(imageRaw, img0);
cvtColor(img0, img0, CV_BGRA2BGR);
UIImageToMat(drawingRaw, drawingMask, true);
cvtColor(drawingMask, drawingMask, CV_BGRA2BGR);
img = img0.clone();
imgGray = img0.clone();
wshed = img0.clone();
Mat markerMask(img.size(), CV_8UC1);
Mat markers(img.size(), CV_32SC1);
cvtColor(img, markerMask, CV_BGR2GRAY);
cvtColor(markerMask, imgGray, CV_GRAY2BGR);
wshed = Scalar::all(0);
markerMask = Scalar::all(0);
markers = Scalar::all(0);
cvtColor(drawingMask, drawingMask, CV_BGR2GRAY);
markerMask = markerMask + drawingMask;
int i, j, compCount = 0;
vector<vector<cv::Point>> contours;
vector<Vec4i> hierarchy;
findContours(markerMask, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
int idx = 0;
for(; idx >= 0; idx = hierarchy[idx][0], compCount++)
{
drawContours(markers, contours, idx, Scalar::all(compCount+1), -1, 8, hierarchy, INT_MAX);
}
vector<Vec3b> colorTab;
for(i = 0; i < compCount; i++)
{
int b = theRNG().uniform(0, 255);
int g = theRNG().uniform(0, 255);
int r = theRNG().uniform(0, 255);
colorTab.push_back(Vec3b((uchar)b, (uchar)g, (uchar)r));
}
watershed(img0, markers);
for(i = 0; i < markers.rows; i++)
for(j = 0; j < markers.cols; j++)
{
int index = markers.at<int>(i,j);
if(index == -1)
{
wshed.at<Vec3b>(i,j) = Vec3b(255,255,255);
}
else if(index <= 0 || index > compCount)
{
wshed.at<Vec3b>(i,j) = Vec3b(0,0,0);
}
else
{
wshed.at<Vec3b>(i,j) = colorTab[index - 1];
}
}
wshed = wshed*0.5 + imgGray*0.5;
return MatToUIImage(wshed);
}