Blurring non-rectangular region of an image, then downsample whole image - OpenCV - c++

I am using OpenCV3 to blur and downsample an image, I just want to blur the region inside the area defined by a binary mask like:
After that region is blurred, I would like to downsample the image without blurring the whole image again, so pyrDown is not useful for me.
Any idea?

Tricky way:
cv::Mat roi;
cv::blur(image & mask,roi,cv::Size(3,3));//Or whatever blurring you want
cv::Mat Result=(image & (~mask)) + roi;
cv::resize(result,result,cv::Size(New_Width,New_height)); // Or whatever downsampling you want

Related

In open cv, how can i convert gray scale image back in to RGB image(color)

In open cv to remove background, using current frame and former frame, i applied absdiff function and created a difference image in gray scale. However, i would like to covert the gray scale image back in to RGB with actual color of the image, but i have no idea how to operate this back in.
I'm using C++.
Could any one knowledgeable of open cv help me?
You cannot covert the gray scale image back into RGB with actual color of the image again as coverting RGB to gray scale is a data-losing process.
Instead, as #MatsPetersson suggested, you can take the use of the grayscale image to create a mask, e.g. by further applying a thresholding process. Then you can easily get the ROI color image by:
cv::Mat dst;
src.copyTo(dst, mask);

Image resize vs Image pyramid for generating ROI for pedestrian detection - OpenCV

For a OpenCV driving assistance application I want to generate ROIs as candidates for faster HoG classification of pedestrians. I'm running this on GPU. I do not want to use detectMultiscale function as it scan all over the image (including sky). Since the features are not scalable, which of the following functions I should use for resizing the images for generating the ROIs?
gpu::resize(const GpuMat& src, GpuMat& dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR, Stream& stream=Stream::Null()) or
Image pyramids cv2.pyrUp(), cv2.pyrDown()
I couldn't find image pyramids in OpenCV GPU library(2.4.9).
Can anyone please suggest?
Thanks
First, you could directly set a ROI by using the cvRect (opencv rectangle) function to create the ROI image/submatrix, like that:
Mat image = imread("");
Rect region_of_interest = Rect(x, y, w, h);
Mat image_roi = image(region_of_interest);
But if you want to generate lowsamples smaller (less lines and columns), there are some differences between pyramids and resize:
-Pyramids are a kind of filter done by a convolution of all image with a gaussian convolution matrix, and after that it downsamples the image by rejecting even rows and columns.
-The resize function, do a geometric transformation and you could change the method to interpolate the pixel values.
in pratice: pyramids are a quick way to downsample by 4 sub-images; resize are more generic and could be used for upsampling too.

Stereo rectify - ROI have different sizes

I have done a stereo calibration and I got the validPixROI1 and 2 (green border). Now I want to use StereoSGBM but the rois from calibration (from stereoRectify) are not the same size. Anyone know how to solve this?
Actually I do somethine linke this:
Rect roiLeft(...);
Rect roiRight(...);
Mat cLeft(rLeft, roiLeft);
//Mat cRight(rRight, roiRight); // not same size...
Mat cRight(cRight, roiLeft);
stereoBM(cLeft,cRight, dst);
If I crop my images with that roi, will be the picture middle point be the same?
Here it works.
Why not run stereoBM on the (uncropped)calibrated images, then you can use those ROIs after to mask out the invalid bits of the result...
stereoBM(rLeft,rRight, disp);
//get intersection of both rois or use target image roi, if you know the target image
cv::Rect visibleRoi = roiLeft & roiRight;
cv::Mat cDisp(disp,visibleRoi);
Now you have no issues with different size inputs, or different centers and such.
Cheers
According to wiki
A point R at the intersection of the optical axis and the image plane. This point is referred to as the principal point or image center.
So I don't think the center will be same.
Refer to this site . Here in one of the examples the principal point is 302.71656,242.33386 for a 640x480 pixel camera which shows that the principal point and the image center are not the same.
Run the block matcher on the uncropped rectified images and then use.
cv::getValidDisparityROI(roi1, roi2, minDisparity, numberOfDisparities, SADWindowSize);
That call returns a cv::Rect that will be a bounding box for all the valid pixels in the left image and the disparity map. The valid pixels are only pixels that both cameras can "see" (caveat on occluded edges).
Once you have the disparity map the right image becomes useless.
Be aware that the roi's returned from stereoRectify are just valid pixels after the remap from the cameras intrinsics.

Is it possible to copy a rotated image into a rotatedrect ROI of another image with opencv?

Ok sorry for asking pretty much the same question again but I've tried many methods and I still can't do what I'm trying to do and I'm not even sure it's possible with opencv alone.
I have rotated an image and I want to copy it inside another image. The problem is that no matter what way I crop this rotated image it always copies inside this second image with a non rotated square around it. As can be seen in the image below.(Forget the white part thats ok). I just want to remove the striped part.
I believe my problem is with my ROI that I copy the image to as this ROI is a rect and not a RotatedRect. As can be seen in the code below.
cv::Rect roi(Pt1.x, Pt1.y, ImageAd.cols, ImageAd.rows);
ImageAd.copyTo(ImageABC(roi));
But I can't copyTo with a rotatedRect like in the code below...
cv::RotatedRect roi(cent, sizeroi, angled);
ImageAd.copyTo(ImageABC(roi));
So is there a way of doing what I want in opencv?
Thanks!
After using method below with masks I get this image which as seen is cut off by the roi in which I use to say where in the image I want to copy my rotated image. Basically now that I've masked the image, how can I select where to put this masked image into my second image. At the moment I use a rect but that won't work as my image is no longer a rect but a rotated rect. Look at the code to see how I wrongly do it at the moment (it cuts off and if I make the rect bigger an exception is thrown).
cv::Rect roi(Pt1.x, Pt1.y, creditcardimg.cols, creditcardimg.rows);
creditcardimg.copyTo(imagetocopyto(roi),mask);
Instead of ROI you can use mask to copy,
First create mask using rotated rect.
Copy your source image to destination image using this mask
See below C++ code
Your rotated rect and I calculated manually.
RotatedRect rRect = RotatedRect(Point2f(140,115),Size2f(115,80),192);
Create mask using draw contour.
Point2f vertices[4];
rRect.points(vertices);
Mat mask(src.rows, src.cols, CV_8UC1, cv::Scalar(0));
vector< vector<Point> > co_ordinates;
co_ordinates.push_back(vector<Point>());
co_ordinates[0].push_back(vertices[0]);
co_ordinates[0].push_back(vertices[1]);
co_ordinates[0].push_back(vertices[2]);
co_ordinates[0].push_back(vertices[3]);
drawContours( mask,co_ordinates,0, Scalar(255),CV_FILLED, 8 );
Finally copy source to destination using above mask.
Mat dst;
src.copyTo(dst,mask);

Best practice, to detect if a Mat is black and White in Opencv

I would like to know if the image I read is a Black and white or colored image.
I use Opencv for all my process.
In order to detect it, I currently read my image, convert it from BGR2GRAY and I compare Histogram of the original(read as BGR) to the histogram of the second (known as B&W).
In pseudo code this looks like that:
cv::Mat img = read("img.png", -1);
cv::Mat bw = cvtColor(img.clone(), bw, CV_BGR2GRAY);
if (computeHistogram(img) == computeHistogram(bw))
cout << "Black And White !"<< endl;
Is there a better way to do it ? I am searching for the lightest algo I can Implement and best practices.
Thanks for the help.
Edit: I forgot to say that I convert my images in HSL in order to compare Luminance Histograms.
Storing grayscale images in RGB format causes all three fields to be equal. It means for every pixel in a grayscale image saved in RGB format we have R = G = B. So you can easily check this for your image.