I need help with a sample code which is using python language to get the length of vertical and horizontal lines of an uploaded image.
Didn't got your question correctly. But here is something according to my understanding.
First, detect the lines:
Line detection using OpenCV
Second, use the formula to calculate the distance between two points:
length = norm(p2 - p1)
where p1(x1,y1) and p2(x2,y2)
Note: It will calculate length in pixels.
You can use cv2.findContours and cv2.approxPolyDP. This will get you a list of rectangles, then you can analyse if they are vertical or horizontal.
Some info:
https://docs.opencv.org/3.1.0/d4/d73/tutorial_py_contours_begin.html
https://docs.opencv.org/3.1.0/dd/d49/tutorial_py_contour_features.html
Related
what OpenCV Python tool would be the best to draw a straight line between multiple 'points' on an image ?
Something like a BestFitLine but for thresoldedimage, not a plot
Thanks
source image
processed image (binary threshold)
the black dot are supposed to be each individual crop
what I'd like to have
I'm afraid Hough Lines will fail here. You could try ransac to get best estimated line, erase those points and run next ransac. Tough you still can encounter some troubles: exactly how many clusters do you want to recognize? You could set min score sample score for a line model. You'd also need to filter out horizontal lines.
There're ransac implementations in both scikit-learn and scikit-image.
If you haven't tried yet, go with the OpenCV functions HoughLines() and HoughLinesP() to detect lines in an image.
I'm currently trying to write a program that can automatically extract data from some graphs in multiple scanned documents. Mainly by using opencv I would like to detect some features of the graphs in order to convert them into usable data. In the left graph I'm looking for the height of the circle sectors and in the right graph the distance from the center to the points where the dotted lines intersect with the gray area. In both cases I would like to convert these values into numeric data for further usage.
What follows is a step by step plan of how I think my algorithm will work:
Align the image based on the big dotted lines. This way I can ensure that the graphs in all the scanned images will have the exact same positions. After all, it is possible that some images will be slightly tilted or moved in comparison with other images, due to the manual scanning process. Basically I want the coordinate of a pixel in one image to correspond to the exact same pixel in another image.
We now know that the coordinates of the graph centers and the angles for the circle sectors are identical for all images now. For each circle sector, filter the darker pixels from the lighter ones. This is done using the openCV inRange function.
Search for the best fitting segment over the darker pixels in the left graph and search for the best fitting triangle in the right graph. This is done by global optimization.
Return the radius of the optimal segment and return the edge lengths of the optimal triangle. Now we have values that we can use as data.
I have more or less figured out how to do every step, except the first one. I have no clue on how I would go about aligning my images. Does someone might have an idea or a strategy on how to achieve this alignment?
Step 1: canny, it give you perfect long edge. If this is the only part you dont understand, here is the answer. You can adjust the parameter to get the best result. The first will be idea for both line and pie circle. But if you only keen to find pie. change the parameter accordingly to get my 2nd image
The red denotes the doted line. sample from opencv directly
Step 2: local area enhancement/segmentation to find both circles (from image 1 parameter with houghcircle param2 set to 110)
Step 3: Segment the pie out(all the way to the edge of image) and find the median line
Step 4: OCR on the test image pies and find the distance of none-background color along the median line.
Step 5: generate list out and send to csv or sth
I am trying to extract the tiles ( Letters ) placed on a Scrabble Board. The goal is to identify / read all possible words present on the board.
An example image -
Ideally, I would like to find the four corners of the scrabble Board, and apply perspective transform, for further processing.
After Perspective transform -
The algorithm that I am using is as follows -
Apply Adaptive thresholding to the gray scale image of the Scrabble Board.
Dilate / Close the image, find the largest contour in the given image, then find the convex hull, and completely fill the area enclosed by the convex hull.
Find the boundary points ( contour ) of the resultant image, then apply Contour approximation to get the corner points, then apply perspective transform
Corner Points found -
This approach works with images like these. But, as you can see, many square boards have a base, which is curved at the top and the bottom. Sometimes, the base is a big circular board. And with these images my approach fails. Example images and outputs -
Board with Circular base:
Points found using above approach:
I can post more such problematic images, but this image should give you an idea about the problem that I am dealing with. My question is -
How do I find the rectangular board when a circular board is also present in the image?
Some points I would like to state -
I tried using hough lines to detect the lines in the image, find the largest vertical line(s), and then find their intersections to detect the corner points. Unfortunately, because of the tiles, all lines seem to be distorted / disconnected, and hence my attempts have failed.
I have also tried to apply contour approximation to all the contours found in the image ( I was assuming that the large rectangle, too, would be a contour ), but that approach failed as well.
I have implemented the solution in openCV-python. Since the approach is what matters here, and the question was becoming a tad too long, I didn't post the relevant code.
I am willing to share more such problematic images as well, if it is required.
Thank you!
EDIT1
#Silencer's answer has been mighty helpful to me for identifying letters in the image, but I want to accurately find the placement of the words in the image. Hence, I feel identifying the rows and columns is necessary, and I can do that only when a perspective transform is applied to the board.
I wrote an answer on MSER text detection:
Trying to Plot OpenCV's MSER regions using matplotlib
The code generate the following results on your images.
You can have a try.
I think #silencer has already given quite promising solution.
But to perform perspective transform as you have mentioned that you have already tried with hough lines to find the largest rectangle but it fails because for tiles present.
Given you have large image data set may be more than 1000 images, you can also give a shot to Deep learning based approach where you can train a model with images as input and corresponding rectangle boundary points coordinate as outputs.
I'm working on writing a document scanner, and I've come across a problem. Here's the general pipeline of my app:
- Detect edges in the image
- Find straight lines in the edge image
- Find all quadrilaterals of a certain area formed by the intersections of those lines
- Determine which quad is the document by looking at the ratio of edge pixels vs total pixels on the perimeter of each quad and using the max
However, that last step is extremely slow for large images because I generate and test all coordinates in the image. Is there a faster way to generate the x,y coordinates of an image that lay on the perimeter of a particular quadrilateral?
The project is in Python, if that helps.
Thanks!
Can't believe I forgot about Bresenham's Line Algorithm. Problem solved
The following paper gives you an idea about tripwire.
I have subtracted the background from foreground using backgroundsubtractormog2 method of OpenCV C++.
I can able to find and draw contours but how to draw a line such that whenever a person or vehicle is crossing that line, it should be counted. you can see a sample video here example video.
Any suggestions on drawing such a line......
Is the way I am approaching is correct? I am using Windows 7 OpenCV 2 & OpenCV 3 in python and C++
For drawing a line you can use the cv::line function.
For counting objects passing the line you can use the minimum and maximum (x,y) values of the contour or bounding box you know. If the contour has passed the line, then both minimum and maximum (x,y) will be on the other side of that line.
Can you show us the code of what you've already tried?