Reputation: 1825
My project takes a bitmap snapshot of the client area of a given window, and converts this data into an IplImage
instance. Then after a grayscale conversion, threshing etc, bounding boxes are drawn around any contours which exceed a given minimum size (area volume).
The result is then shown within a cvNamedWindow
All I need to do now is allow the user to click within these rects to effectively "choose" this contour, so that the application can then extract the subrect as a new image and save it to disk.
How can this be achieved using OpenCV in C++?
Upvotes: 1
Views: 871
Reputation: 1825
In case anyone else was interested on how to actually extract the chosen image,
here's how I was able to do it:
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;
}
}
}
}
Upvotes: 0
Reputation: 1531
If you store your bounding boxes you can check in a for loop in a mouse event handler if a box is clicked and which box is clicked. The code for creating a mouse event:
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);
}
}
You can probably find out yourself how to check if these coordinates are within a bounding box. I would also recommend to use the C++ API, as stated in the comments, as it is much easier once you get the hang of it.
Upvotes: 2