Detecting a photograph (i.e. rectangle) on screen using find contours? - c++

I'm trying to detect a photograph in front of the screen with OpenCV (using a webcam). I am using the following code, which uses findContours() to detect rectangles (which for my purpose would count as a photograph.
https://github.com/opencv/opencv/blob/master/samples/cpp/squares.cpp
This works well, but findContours expects a white background against black, so the image needs to be inverted. I tried changing the threshold, but i still can't get it to detect a photograph.
Am i going about this the right way or would there be a better approach to this.
Thank you for your time!

Related

Shape Detection Using OpenCv

I am working on Image Processing and for that i am using OpenCV Library in c++.
I have one image in which i want to detect particular shape and mainly want its point.
I have below image , where four black corners are there.I want to detect four corner points as i have drawn with red color.
And please note that image can be at any angle or position. Not straight always.
I have tried cv::threshold, canny, findContours, minAreaRect but I am not getting expected output.
Please anybody can help me.Thanks in Advance.
OpenCV has a function to detect corners using the Harris-Stephens method, here is a tutorial with C++ code example.

Dynamic background separation and reliable circle detection with OpenCV

I am attempting to detect coloured tennis balls on a similar coloured background. I am using OpenCV and C++
This is the test image I am working with:
http://i.stack.imgur.com/yXmO4.jpg
I have tried using multiple edge detectors; sobel, laplace and canny. All three detect the white line, but when the threshold is at a value where it can detect the edge of the tennis ball, there is too much noise in the output.
I have also tried the Hough Circle transform but as it is based on canny, it isn't effective.
I cannot use background subtraction because the background can move. I also cannot modify the threshold values as lighting conditions may create gradients within the tennis ball.
I feel my only option is too template match or detect the white line, however I would like to avoid this if possible.
Do you have any suggestions ?
I had to tilt my screen to spot the tennisball myself. It's a hard image.
That said, the default OpenCV implementation of the Hough transform uses the Canny edge detector, but it's not the only possible implementation. For these harder cases, you might need to reimplement it yourself.
You can certainly run the Hough algorithm repeatedly with different settings for the edge detection, to generate multiple candidates. Besides comparing candidates directly, you can also check that each candidate has a dominant texture (after local shading corrections) and possibly a stripe. But that might be very tricky if those tennisballs are actually captured in flight, i.e. moving.
What are you doing to the color image BEFORE the edge detection? Simply converting it to gray?
In my experience colorful balls pop out best when you use the HSV color space. Then you would have to decide which channel gives the best results.
Perhaps transform the image to a different feature space might be better then relying on color. Maybe try LBP which responds to texture. Then do PCA on the result to reduce the feature space to 1 single channel image and try Hough Transform on that.

Detecting colored objects on a image which contains a dark background

I'm currently using OpenCV to try to detect objects on a black cloth covered table. The camera will not always be looking at the same direction (it's a robot's head) but only one image will be processed, so speed is not an imperative. I haved used cv::Canny and cv::findContours with the most adequate parameters I could find, before removing contours which have a too small area. This gets me close to the result I want but some contours which are not in the table area are obviously detected.
What would be a good way to filter those ?
I was thinking of three solutions (which could be combined for better results) :
Cropping the image to just keep the table area, but I can't think of a good criteria (cv::HoughLines ?).
Removing contours which are not closed. This does not limit itself to convex contours (the orange dolphin on the right is not, for instance). Would checking the distance between the first cv::Point and the last cv::Point in the contour (which is a vector<cv::Point>) work ?
Studying a circle a few pixels outside of each contour and check the HSV channels to find out if all pixels of the circle are dark enough to be considered as part of the table.
If anyone has an efficient way to filter those contours, or just input and advice about one of the filtering methods above, it would be just great. Also the robot hand you can see on the bottom right will not be an issue because they will be out of the field of view during the real experiment.

ideas for removing background fringes using opencv

basically i wrote a code that had two images. a reference img and a background img. So far i have successfully found the matching image by using feature recognition. Then i rotated it and resized it to look identical as the reference image. The only problem left is the fact that the image as some of the background image on the fringes of the object. This image has been appropriately cropped so i just need to work with the image below. The most obvious answer that first came to me was perhaps use a edge detection algorithm (canny) and use that to give me a clue on where the background may lie. However since the images itself could technically be anything i feel like there would be lots of noise and various unusual errors so if possible i would rather not want to take that path. I also saw the backgroundsubtraction MOG but it seemed like that works for videos and not for single stilled image. In case i was wrong i tried the following code but had 0 effect:
BackgroundSubtractorMOG bs_mog(3, 4, 0.8);
Mat foreground_mog;
bs_mog (cropped_img, foreground_mog, -1.0);
Perhaps i am doing it wrong. So my thought is other than edge detection and if backgroundsubtractorMOG is only for moving images are there any other ideas or options i can look into to remove the fringe background image (i want to turn it all into just white)
thank you in advance for your ideas and comments
EDIT:
well i unerstand the logic already posted by others but i am unsure what the best way to make a mask for this bottom image would be. It is important to note that the image can technically be anything. Not necessary round in shape. Also due to changes in the algorithm the shape must be resized after the object is separated from the background. This means i can't use my reference image to just make a mask and use that mask on this image due to the difference in size.
Segmentation could work. Try cvgrabCut() with a customized mask.
Set as background all pixels very close to borders. (red in image below)
Set as foreground the center area of your image. (green in image below)
Any intermediate pixels set them to probably foreground. (gray in image below)

Extract Rectangle From Contour OpenCV

after making some edge and corner detection and then find contours i have this output.
how i can crop this image and return only this rectangle using openCV
EDIT:
i tried cvBoundingRect and then setimageROI but the output image still having some background but i want the rectangle only
Thank You.
i hope you need the rectangle area you selected.
For this you need to make another grayscale image, let us call it 'mask'. Then draw the rectangle contour obtained on it and fill it with white (255,255,255). You will obtain an image like this ( all images hand-edited in paint program):
Now just have an bitwise_and operation on both the images. You will get result as this:
**NB:**Now if it is not the one you wanted, instead you wanted this kind of selection, You can find information about it in this SOF question (thanks to karl philip for the link) .
I guess Mustafa wants to get the box automatically? If not, please accept Abid's answer and ignore this one.
Otherwise:
As I don't know how far it should generalize, for this specific image, do hough transform, which gives you straight lines. However the line at the bottom can become false positive. But with some post processing, e.g. blur, dilate, you will be able to get rid of it. Or you could use the knowledge that the lines build a rectangle.