OpenCV C++, getting Region Of Interest (ROI) using cv::Mat - c++

I'm very new to OpenCV (started using it two days ago), I'm trying to cut a hand image from a depth image got from Kinect, I need the hand image for gesture recognition. I have the image as a cv::Mat type. My questions are:
Is there a way to convert cv::Mat to cvMat so that I can use cvGetSubRect method to get the Region of interest?
Are there any methods in cv::Mat that I can use for getting the part of the image?
I wanted to use IplImage but I read somewhere that cv::Mat is the preferred way now.

You can use the overloaded function call operator on the cv::Mat:
cv::Mat img = ...;
cv::Mat subImg = img(cv::Range(0, 100), cv::Range(0, 100));
Check the OpenCV documentation for more information and for the overloaded function that takes a cv::Rect. Note that using this form of slicing creates a new matrix header, but does not copy the data.

Maybe an other approach could be:
//Create the rectangle
cv::Rect roi(10, 20, 100, 50);
//Create the cv::Mat with the ROI you need, where "image" is the cv::Mat you want to extract the ROI from
cv::Mat image_roi = image(roi)
I hope this can help.

Related

OpenCV - Using ROI after a cvtColor

I am doing some ellipse recognition in an image and in order to do so I am opening a simple image:
img = imread("M:/Desktop/PsEyeRight.jpg", CV_LOAD_IMAGE_COLOR);
selecting a ROI (that's the only way I could see to set a ROI in OpenCV 2.4.6 where the old library had a cvSetImageROI() and cvResetImageROI() which I think were more simple):
Mat roi(img, Rect(Point(205, 72), Point(419,285)));
changing its color space with cvtColor:
cvtColor(roi, roi, CV_BGR2GRAY);
applying Threshold:
threshold(roi, roi, 150, 255, THRESH_BINARY);
Then I do the findContours with a cloned image since findContours modifies the image passed in the function and then I change the ROI back to BGR color space:
cvtColor(roi, roi, CV_GRAY2BGR);
And draw all the found ellipses in roi.
When I show roi I can see that everything worked 100% but I was expecting that when I showed the original image, it will be the original image with the ROI in threshold and the drawings inside of it, but instead I just get the original image itself, like nothing has changed. I believe this is happening because cvtColor is copying roi, so it doesn't "point" to img any more.
What's the best way (or recommended) to do this same processing and have the ROI inside the original image, showing the progress of the algorithm?
the main problem is, that you can't have an image, which is partly 3chan/rgb and partly 1chan/gray.
my solution would be , to work on a copy of the roi in the 1st place, and later convert it back to rgb and paste it into the original image.
img = imread("M:/Desktop/PsEyeRight.jpg", CV_LOAD_IMAGE_COLOR); // original
Mat roi(img, Rect(Point(205, 72), Point(419,285)));
Mat work = roi.clone();
cvtColor(work , work , CV_BGR2GRAY);
threshold(work , work , 150, 255, THRESH_BINARY);
// findContours(work,...);
cvtColor(work , roi, CV_GRAY2BGR); //here's the trick

opencv set picture dimension

Hy,
I am using OpenCV2.4.4 to develop the following application:
read an image in Mat format;
transform it to grayscale;
detect the face, if exists;
crop the face, extracting the Region Of Interest;
save the cropped image to file.
My question is: could I possible set a standard dimension for the saved image (width and height)?
I tried to use resize function, but it doesn't actually I want because saves just a part of the face.
cv::cvtColor(croppedImage, greyMat, CV_BGR2GRAY);
greyMat.resize(100);
imwrite("result.jpg", greyMat);
Try to use cv::resize instead:
cv::cvtColor(croppedImage, greyMat, CV_BGR2GRAY);
cv::Mat result;
cv::resize(greyMat, result, cv::Size(100,100));
imwrite("result.jpg", result);
See the documentation for details.

Calibrating my camera with OpenCV

I would like to apply a color map on a grayscale image, with applyColorMap but it seems that it doesn't take into consideration the IplImage pointers, according to :
http://docs.opencv.org/trunk/modules/contrib/doc/facerec/colormaps.html
What would be the right syntax for that?
Something else, is there a link between Camera Calibration and Color Mapping? Is it about the same thing?
You can pass a cv::Mat to applyColorMap according to the ColorMaps page in the OpenCV documentation.
Looking at this OpenCV C++ cheat sheet we see that an IplImage can be converted to a Mat by simply passing the IplImage to the Mat constructor: Mat imgMat(iplimg);

Converting old Opencv code to the new C++ API, replacement for cvGetSubRect?

I am converting some old OpenCV code using the C api to the new C++ API in OpenCV 2.3. I am wondering what the method is to replace the cvGetSubRect call is?
I have the following, cvGetSubRect(some_cv_mat_pointer, another_cv_mat_pointer, some_cv_rect);
What is the equivalent to this in the C++ api?
You create an roi on the source image which gives you a new image - there is no actual pixel copying it all happens automatically
Mat image(.....) // original image
Rect roi(10, 20, 100, 50); // shape of roi
Mat image_roi = image(roi); /// really a window into image, copy it if you need to change it
http://opencv.willowgarage.com/documentation/cpp/c++_cheatsheet.html

How to make a deep copy of a rectangular region of a cv::Mat?

Using opencv 2.3. I have a region bounded by a rectangle that I want to extract and make a deep copy of, so that when that image is destroyed this rectangular region can live on. I'm using this as a template for matching in a video sequence. How can you do that?
Quoting OpenCV 2.3 online documentation use this constructor to create rectangular region of interest of a cv::Mat:
// select a ROI
Mat roi(img, Rect(10,10,100,100));
and then to make a deep copy do:
Mat deepRoiExplorer=roi.clone();
You can use Mat::clone() to copy a ROI to a new image, or you can create the target image yourself and use Mat::copyTo():
Mat source...; // your source image
Rect sourceRect(...); // your ROI
// using clone
Mat target = source(sourceRect).clone();
// using copyTo
Mat target(sourceRect.size(), source.type());
source(sourceRect).copyTo(target);