Image processing : Improved thresholding? - c++

I would like to apply a rotation on image of scanned book.
I use FindContours and approxPolyDP to get the corners of the book and for that I need a perfect white square. Only, when I apply a simple threeshold:
threshold(imgGrayScale, three, 1, 255, THRESH_BINARY);
on my input image I have still some points here and there. Thresholding it is the good solution to get a full perfect white square? Maybe Segmentation would be a better solution?
Summary of my post :
http://imgur.com/FWp28rr

Related

Is there any way to "approximate" the rest of a circle in OpenCV?

I am trying to detect circles in some pictures but the circles aren't always perfect. This makes houghCircles very impractical to use because it seems to only support almost perfect circles. So now i am searching for a way to kind of "fix" my circles.
for reproduction purposes:
First i threshold the picture to get a binary picutre:
cv::threshold(input, output, threshvalue, 1, cv::THRESH_BINARY_INV);
After thresholding i detect the Hough Circles with :
std::vector<cv::Vec3f> circles;
HoughCircles(binarypicture,circles,cv::HOUGH_GRADIENT,1,100,30,26,45);

OpenCV Adaptive Thresholding a HSV image

We (my group and I) want to be able to track a hand (well the index fingertip mostly). The hand is basically the same colour as the face in the picture, but as you can see, so is a lot of the noise we get. It works very well with a black "screen" behind the hand.
Now the problem is that Adaptive thresholding is useful only on Grayscale images, and as such would not detect the hand very well.
I've tried googling HSV Adaptive Thresholding but no luck, so I figured stackoverflow had some great ideas.
EDIT: The current HSV -> Binary threshold:
inRange(hsvx, Scalar(0, 50, 0), Scalar(20, 150, 255), bina);
I suggest you use a color histogramming for your tracking. Camshift is doing it for example to good success.
There is camshift sample code in OpenCV.
See http://docs.opencv.org/master/db/df8/tutorial_py_meanshift.html (very brief explanation)
or https://github.com/Itseez/opencv/blob/master/samples/cpp/camshiftdemo.cpp (code sample)
If you want to go with your thresholding, you are already proper about not thresholding the V channel. I would still suggest to do separate adaptive thresholding on H and S.
I would suggest you using a histogram backprojection algorithm.
Back Projection is a way of recording how well the pixels of a given image fit the distribution of pixels in a histogram model. You can specify the histogram model by using manually selected set of hand-pixels.
This algorithm outputs an image where each pixel has the value of likelihood the color of this pixel is a color of the skin (is similar to the skin). You can then specify a likelihood threshold to adjust the performance.
It will let you find the skin-colured areas in the image.
For details see:
http://docs.opencv.org/2.4/doc/tutorials/imgproc/histograms/back_projection/back_projection.html
http://docs.opencv.org/master/dc/df6/tutorial_py_histogram_backprojection.html#gsc.tab=0

OpenCV C++ set ROI from a rectangular area

Anyone know how to set ROI based on image bellow?
I used Hough Transform to detect the white line and draw the red line into the image.
What I need to do is to set the ROI in the rectangle.
Since Hough Transform unable to get location of each rectangle and the main problem is I cannot defined the location (x,y) manually.
Any solution that able to auto detect the rectangle and set the ROI?
Anyone can give some idea for me or the code can be use?
Please forgive my poor english and thank you.
this blog post is very good in explaining how to find a rectangle with the hough transform and it has also some c++ code with opencv 2 API.
The approach is to find lines, intersect them, and find the rectangle. In your case you will have more rectangles and so it's a little bit more complicated..
But if you manage to obtain such image.. why don't use just some threshold and find connected regions (aka blob)?

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.

OpenCV - find or access shape contour not surrounded by bg, only separated by an outline

I've been trying to find the contour of a single shape in a very plain background using OpenCV's findContour (I'd like to use the C++ syntax). However, it keeps on making its outline a contour and not the shape itself. I'm thinking it's because of the white edge resulted from Canny which doesn't make the shape closed.
Case A: Shape is by the image's edge
(This is not the actual input image but a simpler input image to illustrate this problem.)
Case B: Background surrounds the shape
There are the main functions I used:
findContours( grayImage, contours, hierarchy, RETR_LIST,CHAIN_APPROX_SIMPLE);
approxPolyDP(Mat(contours.at(largestContourIndex)),poly,3,true);
drawContours(output, contours, largestContourIndex, RGB(250,0,100), -1, 8, hierarchy, 0, Point() );
EDIT: Skipping edge detection gives the contour I need but I need to have the best contour approximate I can get.
Thanks in advance.
Did you try playing around with morphology operations?
If your basic problem is that the contour you're getting is on the outside of the object instead of the inside, and especially if your object are made out of so clear-cut and mostly regular shapes, than morphology might help.
I know OpenCV has implementations of dilation and erosion, as well as opening and closing operations. A very simple approach that might work in your situation is just eroding the shape a little bit (maybe 1-2-3 iterations) and then doing exactly what you are doing already. Hopefully, then, you'll get the outer contours of the eroded shape, that should actually be the inner contours of the original shape.
I think OpenCV actually implements even some more complex morphology, but as always, try the simple stuff first :D
It seems to me that the contour you are looking for is probably detected, but you are not using it. Instead you are using the largest contour. Try plotting all found contours one by one and see if it's in there.
If it is not, try inverting the canny image and repeating the process.
I still haven't found the reason why I can't get the shape contour but I found a workaround. After doing erosion and dilation, I basically have to draw a border or a rectangle on the outermost pixels of the input image for the background to surround the shape, ...
rectangle(input,Point(0,0),Point(input.cols-1,input.rows-1),Scalar(0,0,0),1,8,0);
... hence, letting Canny draw a closed shape outline and giving me the shape contour I want. I am still trying to successfully invert Canny's output like what #dvhamme has suggested but it's still giving me errors. It would be better if somebody points out how to properly get or access the shape contour but thanks everyone for the help.