我的项目获取给定窗口的客户区域的位图快照,并将此数据转换为IplImage
实例。然后在灰度转换,脱粒等之后,在超过给定最小尺寸(面积体积)的任何轮廓周围绘制边界框。
结果显示在cvNamedWindow
现在我需要做的就是让用户在这些rects中单击以有效地“选择”这个轮廓,这样应用程序就可以将subrect提取为新图像并将其保存到磁盘。
如何在C ++中使用OpenCV实现这一目标?
答案 0 :(得分:2)
如果存储边界框,则可以在鼠标事件处理程序中检查for循环,如果单击框并单击了哪个框。用于创建鼠标事件的代码:
cvNamedWindow("MyWindow", CV_WINDOW_NORMAL);
cvSetMouseCallback("MyWindow", mouseEvent, 0);
imshow("MyWindow", image);
void mouseEvent(int evt, int x, int y, int flags, void *param) {
if (evt == CV_EVENT_LBUTTONDOWN) {
printf("%d %d\n", x, y);
}
}
您可以自己找出如何检查这些坐标是否在边界框内。我还建议使用C ++ API,如评论中所述,因为一旦掌握了它,它就会容易得多。
答案 1 :(得分:0)
如果其他人对如何实际提取所选图像感兴趣, 这是我能够做到的:
inline
IplImage* getSubImage(IplImage *image, CvRect region)
{
cvSetImageROI(image, region);
IplImage *imgRet = cvCreateImage( cvSize(region.width, region.height), image->depth, image->nChannels );
cvCopy(image, imgRet);
cvResetImageROI(image);
return imgRet;
}
inline
bool pointInRect(const int x, const int y, const CvRect& r)
{
return (
(x > r.x) && (x < (r.x + r.width)) &&
(y > r.y) && (y < (r.y + r.height))
);
}
void onMouseEvent(int evt, int x, int y, int flags, void *param)
{
if (evt == CV_EVENT_LBUTTONDOWN) {
// boundingBoxes is declared as a vector of CvRects and
// filled in the main loop using cvBoundingRect(contour)
for(UINT i = 0; i < boundingBoxes.size(); i++)
{
CvRect rect = boundingBoxes[i].rect;
if( pointInRect(x, y, rect) )
{
IplImage* img = getSubImage(imgSource, rect);
// Do whatever you want with the sub-image here
cvNamedWindow("Selection");
cvShowImage("Selection", img);
cvReleaseImage(&img);
break;
}
}
}
}