Finding keypoints in an handwritten arrow - opencv

I have been trying to find two keypoints (head and tail) in arrows I have drawn,
I was wondering is there a simpler approach than training a CNN, such as a using a classic approach (opencv).
I have used this simple approach:
bi = cv2.bilateralFilter(gray, 5, 75, 75)
dst = cv2.cornerHarris(bi, 2, 3, 0.02)
Here are the images, before:
After some simple image processing I get:
I could pick the two red dots with the longest euclidean distance (checking all combinations of pairs), but sadly for the self loop case it won't give me the correct result. can someone suggest me a better approach?
Any suggestion is highly appreciated, thank you all!

The image is quasi-binary. Consider binarization followed by thinning. You can find the tips and junctions. You can also follow the arcs.

Related

Most 'fitting' placement of shape in silhouette

I apologize in advance for the lack of code, but I have been looking at this problem for some days now and couldn't proceed much.
I am trying to find a method that, given a template shape and a figure, finds the most fitting (edges-wise) placement of such shape in the (binarized) figure.
For example, in the picture above, I've highlighted 2 placement for the triangle on the right (I show 2, but there are probably 5). The blue one covers more "perimeter" and thus should be preferred.
The rotations are limited to steps of 45 degrees and no scaling is involved, so I don't think I need some particularly rotation/size invariant methods.
For now, I have obtained some results using opencv template matching, by first extracting the edges with canny and matching the resulting contour, but it is far from precise and I am afraid this would not work for more complex figures. Also by using canny I lose information about the binarized foreground and background, while the placement must be only inside the figure.
Any idea would be appreciated because I really could not find much in the literature (also I am quite inexpert in the field and probably lacking the proper terminology for effective searches), thank you in advance

Is it possible to make two grayscale images stastistically equivalent?

I have 2 grayscale images say G1 and G2 . I also have the statistics (min ,max ,mean and Standard Deviation). I would like to change G2 such that the statistics of G2 (min ,max,mean and SD)match G1. I have tried arithmetic scaling and got the min and max values of both G1 and G2 to match but mean and SD are still different. I have also tried Histogram fitting of G2 in G1 but that did not do what i wanted either. I am using a software called SPIDER this a question applicable to image-processing which can be performed using different software packages(OpenCV MATLABetc) .Any ideas and suggestions would be greatly appreciated.
The easiest thing to do is to apply histogram equalization to both images (histeq in MATLAB). If you do not want to change both images, then you can do histogram matching, but that's a bit more complicated.
You can generate a mapping of input to output based on a simple curve. Start with the values that don't have any dependencies, min and max - those will set the ends of the curve. Now map the mean values to create a single point in the middle of the curve. To modify the standard deviation, you change the shape of the curve between the mean and the endpoints - a curve that is flatter in the middle will give less deviation, and a curve that is flatter towards the ends but steeper in the middle will magnify it.
Edit: I haven't given this enough thought yet, changing the shape of the curve will also change the mean. But I think it can be worked into something usable.
I marked the histogram equalization answer as right because it gave me the best results however I was unable to make the 2 images exactly statistically equivalent as such

Detecting blobs of uniform colour with openCV

I am working on a program to detect split fields for remote sensing (ie. more than one colour/field type within each image, where the image corresponds to the land owned by one farmer) and have been trying to find a solution by reading in images and posterizing them with a clustering algorithm, then analysing the colours and shapes present to try and 'score' each image and decide if more than one type of field is present. My program works reasonably well although there are still quite a few obvious splits that it fails to detect.
Up until now I have been doing this using only standard libraries in c++, but I think now that I should be using openCV or something and I was wondering which techniques to start with. I see there are some image segmentation and blob detection algorithms, but I'm not sure they are applicable because the boundary between fields tends to be blurred or low in contrast. The following are some sample images that I would expect my program to detect as 'split':
(True colour Landsat)
http://imgur.com/m9qWBcq
http://imgur.com/OwqvUvs
Are there any thoughts on how I could go about solving this problem in a different way? Thanks!
1) Convert to HSV and take H or take gray-scaled form. Apply median filter to smooth the fields :P if images are high-resolution.
2) Extract histogram and find all the peaks. These peaks indicate the different colored fields.
3) (A) Now you can use simple thresholding around these peaks-value and then find canny edges for trapezium or similar shapes.
--OR--
(B) Find canny-edges around the peak value ie for peak with maxima value x, find edge for range of (x - dx) to (x + dx) where dx is a small value to be find experimentally.
4) Now you can extract count of contours at different levels/peaks.
I haven't added code because language is not specified and all these constructs are readily available in OpenCV. Its fun to learn. Feel free to ask further. Happy Coding.
Try the implementations of the MSER algorithm in MserFeatureDetector.
The original algorithm was thought for grayscale pictures, and I don't have good experiences with the color version of it, so try to do some preprocesing of the original frames to generate grayscales according to our needs.

Recognition and counting of books from side using OpenCV

Just wish to receive some ideas on I can solve this problem.
For a clearer picture, here are examples of some of the image that we are looking at:
I have tried looking into thresholding it, like otsu, blobbing it, etc. However, I am still unable to segment out the books and count them properly. Hardcover is easy of course, as the cover clearly separates the books, but when it comes to softcover, I have not been able to successfully count the number of books.
Does anybody have any suggestions on what I can do? Any help will be greatly appreciated. Thanks.
I ran a sobel edge detector and used Hough transform to detect lines on the last image and it seemed to be working okay for me. You can then link the edges on the output of the sobel edge detector and then count the number of horizontal lines. Or, you can do the same on the output of the lines detected using Hough.
You can further narrow down the area of interest by converting the image into a binary image. The outputs of all of these operators can be seen in following figure ( I couldn't upload an image so had to host it here) http://www.pictureshoster.com/files/v34h8hvvv1no4x13ng6c.jpg
Refer to http://www.mathworks.com/help/images/analyzing-images.html#f11-12512 for some more useful examples on how to do edge, line and corner detection.
Hope this helps.
I think that #audiohead's recommendation is good but you should be careful when applying the Hough transform for images that will have the library's stamp as it might confuse it with another book (You can see that the letters form some break-lines that will be detected by sobel).
Consider to apply first an edge preserving smoothing algorithm such as a Bilateral Filter. When tuned correctly (setting of the Kernels) it can avoid these such of problems.
A Different Solution That Might Work (But can be slow)
Here is a different approach that is based on pixel marking strategy.
a) Based on some very dark threshold, mark all black pixels as visited.
b) While there are unvisited pixels: Pick the next unvisited pixel and apply a region-growing algorithm http://en.wikipedia.org/wiki/Region_growing while marking its pixels with a unique number. At this stage you will need to analyse the geometric shape that this region is forming. A good criteria to detecting a book is that the region is creating some form of a rectangle where width >> height. This will detect a book and mark all its pixels to the unique number.
Once there are no more unvisited pixels, the number of unique numbers is the number of books you will have + For each pixel on your image you will now to which book does it belongs.
Do you have to keep the books this way? If you can change the books to face back side to the camera then I think you can get more information about the different colors used by different books.The lines by Hough transform or edge detection will be more prominent this way.
There exist more sophisticated methods which are much better in contour detection and segmentation, you can have a look at them here, however it is quite slow, http://www.eecs.berkeley.edu/Research/Projects/CS/vision/grouping/resources.html
Once you get the ultrametric contour map, you can perform some computation on them to count the number of books
I would try a completely different approach; with paperbacks, the covers are medium-dark lines whilst the rest of the (assuming white pages) are fairly white and "bloomed", so I'd try to thicken up the dark edges to make them easy to detect, then that would give the edges akin to working with hardbacks which you say you've done.
I'd try something like an erosion to thicken up the edges. This would be a nice, fast operation.

OpenCV to find specific co-ordinates in an image

I'm working on an iOS app with OpenCV. I am trying to locate the position of the box around the person. I would like to start by getting the width of the box.
I'm converting the image to Greyscale and then using a Canny edge detector.
Link to image here http://s18.postimg.org/bbpczub2x/sampleshot.png
What would be the best way to get the coordinates of the extreme horizontal ends of the box (marked by the red in the picture)? Any pre-existing functions?
Well I'm going to go ahead and answer this myself. After a bit of digging, I found the Hough Line Transform which perfectly suits my needs.
It is pretty well documented here.
I wanted higher accuracy, so I used HoughLinesP.
HoughLinesP(dst, lines, 1, CV_PI/180, 100, 100, 10);
The arguments are well defined and its pretty much trial and error after that to perfect it. I've used a Median Blur and a Canny Edge Detector before this for better results.

Resources