I found with Hough transform more lines but somethings are very similar for my final target.
For example
In this image I have 5 lines but I really need just 2 lines.
How I can remove the unnecessary lines?
My code is
image = cv.Canny(image, 200);
lines = cv.HoughLinesP(image,'Threshold',80,'MinLineLength',100,'MaxLineGap',50);
A simple way can be with lines intersecting, but lines can be parallel and very close in certain situations.
Any idea?
My crude method was
use canny edge detector
take the first line from houghlines
draw black thick line over the original line in houglines inpu
repeat until you get no output from houghlines
I used it to detect edges of a card, so I took four best lines.
I would compute the the slope and intercept of the lines and compare them to see if they're both within some tolerance you define. The intercept should be described on the same coordinate frame, say with the origin at pixel r,c = (0,0). Identical lines could be merged then. The only failure case I can think of is if you have non-contiguous line segments that would have the same slope and intercept - those would be merged with this approach. But in your image you don't seem to have this issue.
Related
I have been trying to segment lines from a printed text document. I have followed the following paper:
A Hough Transform based Technique for Text Segmentation Satadal Saha, Subhadip Basu, Mita Nasipuri and Dipak Kr. Basu
As per the paper, I used Hough transform to generate straight lines over the text and restricting angles in the vicinity of 90 degrees and connected component algorithm to group the generated straight lines to separate out lines from the text.
The hough transform output is given below:
But, the straight lines generated sometimes overlap between two text lines and more than one line segment gets grouped together.
The bounding boxes of lines in the text is given below:
Can anybody please help me to avoid this grouping together of lines of text? Please suggest a method so that the connected component analysis treat the lines of text as separate components.
You are using connected components to group your hough-lines into text-lines. This process is very sensitive to noise: even one misdetected pixel can bring together two lines.
You can make this process more robust if you look at the average "on" pixels per line in the image:
bw = imread('http://i.stack.imgur.com/tg2xN.png');
bw=bw>100;
figure; plot( mean(bw,2) ); xlabel('image row'); ylabel('#"on" pixels');
The red line shows 7.5% threshold on number of "on" pixels per row. As you can see it can help distinguish between well connected hough-lines to falsely connected ones.
Use this threshold to amend the mask:
msk = bsxfun(#times, bw, mean(bw,2)>0.075);
Now you can get the proper bounding boxes
bb=regionprops(bwlabel(msk,8),'BoundingBox');
Resulting with:
My image is something like below:
I want to be able to draw 2 layers: (1) red line on top of 1st layer, but (2) blue line in the middle of 2nd layer
I am using OpenCV. but any languages/advice are welcomed.
You can do the following:
Small closing in order to reconnect the small separated components/patterns.
Small opening in order to remove the small isolated components/patterns.
Skeletonize (or median axis)
Pruning in order to remove the small branches.
You will then get a skeleton for each pattern. It will be close to the lines you want to draw. But it will be a little bit irregular, so you can interpolate it.
[EDIT] if you need the red line on top of the edge, a solution is to:
Extract the pattern contour
Keep only the pixel on top.
Algorithmically, it can be achieved doing this: for each X coordinate on the top border, go down the image vertically until you meet the first non-null pixel. If your image is NxM, you must have N pixels in your solution.
If you want to regularize/smooth the result, you have two solutions:
Transform the contour as a parametric function and smooth it.
Do an interpolation (spline?)
I'm working on an image processing project where i need to detect corners. But when i try to detect corners using corner function, it detects the small displacements as corners as shown.
I've tried with different thresholds from 0 to 0.24 and couldn't get food results.
imgskele = bwmorph(imgfill,'thin',Inf);
C = corner(imgspur, 'SensitivityFactor', 0.24);
figure; imshow(imgspur);
hold on;
plot(C(:,1), C(:,2),'bo','MarkerSize',10,'MarkerFaceColor','g');
hold off;
So i'm thinking of adjusting(redrawing) the line to make it straight line connecting those points
Edit 1:
Here are the full size original and output images:
The problem which you have is that the corner function is the Harris corner detector, which finds the corner of filled polygons.
Now a line can be approximated by a very thin polygon, certainly when pixelated, but that's not perfect as you notice here.
A more robust method is to use something like the Hough transform to find line features in the image. These lines will have intersections, some of which are approximately the corners you want. Others are fake intersections, because the Hough transform assumes lines and not line segments. You'll need to experiment a bit what you accept and what you reject. How rounded can a corner be, before you no longer call it a corner?
I have a small problem in smoothing a line surface.
The image is a result of edge detection after sobel processing.
It has an uneven surface, and the unit of bulges is one pixel.
Red circle parts are the bulges.
http://www.mathworks.com/help/matlab/creating_plots/smooth-contour-data-with-convolution-filter.html
The link I have tried, but the line width was increased too more.
I have to get a straight line with one pixel width.
How to clear up these bulges?
Many Thanks.
7/21 update:
Canny method can generate a detected image with one pixel.
The result of Canny edge detection:
The line was segmented 2 parts, the under part was shifted by one pixel.
I hope the line that can be considered a straight line rather than 2 lines when the line width is within 2~3 pixel.
With Dilate and Erosion, I tried to smooth the line that become a straight line
Canny > Dilate:
Canny > Dilate > Erosion:
The result of before and after are the same...
Could anyone give me an idea?
Many Thanks again.
If you are working with a simple 2-D, black-and-white image, stored as a 0/1 array, and you guarantee there will always be a straight line all the way from top to bottom, then this may help -
% recreate scenario
A = zeros(100,50);
A(:,25) = 1;
A([30:40,80:85],24)=1;
A([20:35,70:90],26)=1;
% a rude way
S = sum(A,1);
B = repmat(S==max(S),100,1);
imshow(B)
Maybe an approach similar to Canny edge detection could be the solution you are searching for. The Canny edge detector uses non maximum suppression, meaning that the edges are formed only by pixels that have the maximum gradient between their neighbours, resulting in many occasions in one-pixel-width edges.
I'm trying find all straight lines in an image which is border. for example,stamps have four edges and I have already find those edges by edge function in MATLAB. But there is a problem that they are not real straight line. so I need to use line fitting to get all four borders. But polyfit function can only fit one line at one time. Is there any solutions that can fit all lines at one time.
for example:here I upload some pictures,the image with red lines is what I want. Please be ware I need four separate lines.
Judging from the image you won't be trying to smooth some lines, or fill in the gaps. Instead it looks more like you need to put your image in the smallest possible box.
Here is an algorithm that you can try:
Start from all 4 corners.
'walk' one of the corners inwards and determine if all points are still within four corners
If so, save this corner and go to step 2, else go to step 2
Keep repeating step 2 and 3 till you have a steady solution.
Are you trying to get rid of the perforations? In that case I would suggest using thresholding to segment out dark areas of the image, and then using regionprops to get their bounding boxes. Then you can figure out the largest rectangle that excludes them.