Hough变换检测和删除行 [英] Hough transform to detect and delete lines

查看:187
本文介绍了Hough变换检测和删除行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 Hough变换来检测图像中的线条。但是不是绘制我想要删除原始图像中检测到的每一行的线条。

I want to use the Hough transform to detect lines in my image.But instead of plotting the lines I want to delete each line detected in my original image.

image=imread('image.jpg');
image = im2bw(image);
BW=edge(image,'canny');
imshow(BW);
figure,imshow(BW);
[H,T,R] = hough(BW);
P  = houghpeaks(H,100,'threshold',ceil(0.3*max(H(:))));
lines = houghlines(BW,T,R,P,'FillGap',5,'MinLength',7);

此后我已经获得了所有的支持。但是我想从原始图像中删除所有这些线条,保持图像的其余部分。有什么方法可以做到这一点吗?

Now after this I have got all the lines. But I want to delete all these lines from my original image, keeping rest of the image as before. Is there some way I can do this?

编辑我正在上传图片。我想删除所有行并保留圆形部分。这只是一个示例图片。基本上我的目标是删除线段并保留图像的其余部分

Edit I am uploading an image.I want to delete all the lines and keep the circular part.This is just an example image.Basically my objective is to delete the line segments and keep rest of the image

推荐答案

您遇到的问题是您的线条比一个像素厚。
来自霍夫变换的线条似乎是一个像素厚,
没有用。

The issue you have is that your lines are thicker than one pixel. The lines from the hough transform seem to be one pixel thick and that doesn't help.

我建议你删除那些你先从霍夫变换中获得。
这将把曲棍球场的任何分数划分为更容易处理的
分段。

I propose that you delete the lines that you get from the Hough transform first. This will sort of divide the hockey rink of whatever it is into segments that will be easier to process.

然后用每个分段标记每个分段 bwlabel 即可。对于每个对象,找到
端点并在端点之间插入一条线。如果行和对象
的共像像素多于某个阈值,那么我们说对象
是一行,我们将其从图像中删除。

Then you label each segment with bwlabel. For each object, find the endpoints and fit a line between the endpoints. If the line and the object have more pixels in common than a certain threshold, then we say that the object is a line and we delete it from the image.

您可能需要使用霍夫变换的阈值。

You may have to play around with the Hough transform's threshold value.

这种技术虽然存在一些缺陷。它将删除一个填充的正方形,
矩形或圆形,但你没有任何这些,所以你应该没问题。

This technique has some flaws though. It will delete a filled square, rectangle or circle but you haven't got any of those so you should be ok.

这是我修改了一下你的代码。我删除了渐变,因为
更容易使用实体对象。渐变给出了非常细的线条。
我也处理补码图像,因为bw函数与原始图像中的1
一样工作而不是0。

This is your code that I modified a bit. I removed the gradient because it it easier to work with solid objects. The gradient gave very thin lines. I also work on the complement image because the bw functions work with 1 as forgound rather than 0 as in your original image.

org_image_bw=im2bw(double(imread('http://i.stack.imgur.com/hcphc.png')));
image = imcomplement(org_image_bw);
[H,T,R] = hough(image);
P  = houghpeaks(H,100,'threshold',ceil(0.27*max(H(:))));
lines = houghlines(image,T,R,P,'FillGap',5,'MinLength',7);

循环你已经获得的行并删除它们

Loop through the lines you have got and delete them

processed_image = image;
for k = 1:length(lines)
   xy = [lines(k).point1; lines(k).point2];

    % // Use the question of a line y = kx + m to calulate x,y

    % // Calculate the maximum number of elements in a line
   numOfElems = max(max(xy(:,1))-min(xy(:,1)),max(xy(:,2))-min(xy(:,2)) ) ;

   % // Cater for the special case where the equation of a line is
   % // undefined, i.e. there is only one x value.
   % // We use linspace rather than the colon operator because we want
   % // x and y to have the same length and be evenly spaced.
   if (diff(xy(:,1)) == 0)           
       y = round(linspace(min(xy(:,2)),max(xy(:,2)),numOfElems));
       x = round(linspace(min(xy(:,1)),max(xy(:,1)),numOfElems));      
   else

       k = diff(xy(:,2)) ./ diff(xy(:,1)); % // the slope
       m = xy(1,2) - k.*xy(1,1); % // The crossing of the y-axis

       x = round(linspace(min(xy(:,1)), max(xy(:,1)), numOfElems));
       y = round(k.*x + m); % // the equation of a line
   end

   processed_image(y,x) = 0; % // delete the line
end

这是我们删除后图片的外观检测到的线条。请注意,原来的曲棍球场被分成多个物体。

This is what the image looks after we have deleted the detected lines. Please note that the original hockey rink and been divided into multiple objects.

标记剩余的对象

L = bwlabel(processed_image);

运行每个对象并找到终点。
然后在它上面插一条线。如果,假设80%的拟合线覆盖对象的
,那么它就是一条线。

Run through each object and find the end points. Then fit a line to it. If, let's say 80% the fitted line covers the object, then it is a line.

拟合线看起来像这样。蓝色斜线表示拟合线,并覆盖对象(白色区域)的大部分
。因此,我们说该对象是一条线。

A fitted line could look like this. The diagonal blue line represents the fitted line and covers most of the object (the white area). We therefore say that the object is a line.

% // Set the threshold
th = 0.8;

% // Loop through the objects
for objNr=1:max(L(:))
   [objy, objx] = find(L==objNr);

   % Find the end points
   endpoints = [min(objx) min(objy) ...
       ;max(objx) max(objy)];

   % Fit a line to it. y = kx + m
   numOfElems = max(max(endpoints(:,1))-min(endpoints(:,1)),max(endpoints(:,2))-min(endpoints(:,2)) ) ;

   % // Cater for the special case where the equation of a line is
   % // undefined, i.e. there is only one x value
   if (diff(endpoints(:,1)) == 0)           
       y = round(linspace(min(endpoints(:,2)),max(endpoints(:,2)),numOfElems));
       x = round(linspace(min(endpoints(:,1)),max(endpoints(:,1)),numOfElems));      
   else
       k = diff(endpoints(:,2)) ./ diff(endpoints(:,1)); % the slope
       m = endpoints(1,2) - k.*endpoints(1,1); % The crossing of the y-axis           
       x = round(linspace(min(endpoints(:,1)), max(endpoints(:,1)), numOfElems));

       y = round(k.*x + m);
       % // Set any out of boundary items to the boundary
       y(y>size(L,1)) = size(L,1);
   end

   % // Convert x and y to an index for easy comparison with the image
   % // We sort them so that we are comparing the same pixels
   fittedInd = sort(sub2ind(size(L),y,x)).';
   objInd = sort(sub2ind(size(L),objy,objx));

   % // Calculate the similarity. Intersect returns unique entities so we
   % // use unique on fittedInd
   fitrate = numel(intersect(fittedInd,objInd)) ./ numel(unique(fittedInd));
   if (fitrate >= th)
       L(objInd) = 0;
       processed_image(objInd) = 0;
       % // figure(1),imshow(processed_image)
   end       
end

显示结果

figure,imshow(image);title('Original');
figure,imshow(processed_image);title('Processed image');






完整示例




Complete example

org_image_bw=im2bw(double(imread('http://i.stack.imgur.com/hcphc.png')));
image = imcomplement(org_image_bw);

[H,T,R] = hough(image);
P  = houghpeaks(H,100,'threshold',ceil(0.27*max(H(:))));
lines = houghlines(image,T,R,P,'FillGap',5,'MinLength',7);

processed_image = image;
    for k = 1:length(lines)
       xy = [lines(k).point1; lines(k).point2];

        % // Use the question of a line y = kx + m to calulate x,y

        %Calculate the maximum number of elements in a line
        numOfElems = max(max(xy(:,1))-min(xy(:,1)),max(xy(:,2))-min(xy(:,2)) ) ;

       % // Cater for the special case where the equation of a line is
       % // undefined, i.e. there is only one x value.
       % // We use linspace rather than the colon operator because we want
       % // x and y to have the same length and be evenly spaced.
       if (diff(xy(:,1)) == 0)           
           y = round(linspace(min(xy(:,2)),max(xy(:,2)),numOfElems));
           x = round(linspace(min(xy(:,1)),max(xy(:,1)),numOfElems));      
       else

           k = diff(xy(:,2)) ./ diff(xy(:,1)); % the slope
           m = xy(1,2) - k.*xy(1,1); % The crossing of the y-axis

           x = round(linspace(min(xy(:,1)), max(xy(:,1)), numOfElems));
           y = round(k.*x + m); % // the equation of a line
       end

       processed_image(y,x) = 0; % // delete the line
    end


    % // Label the remaining objects
    L = bwlabel(processed_image);

    % // Run through each object and find the end points.
    % // Then fit a line to it. If, let's say 80% the fitted line covers
    % // the object, then it is a line.

    % // Set the threshold
    th = 0.8;

    % // Loop through the objects
    for objNr=1:max(L(:))
       [objy, objx] = find(L==objNr);

       % Find the end points
       endpoints = [min(objx) min(objy) ...
           ;max(objx) max(objy)];

       % Fit a line to it. y = kx + m
       numOfElems = max(max(endpoints(:,1))-min(endpoints(:,1)),max(endpoints(:,2))-min(endpoints(:,2)) ) ;

       % Cater for the special case where the equation of a line is
       % undefined, i.e. there is only one x value
       if (diff(endpoints(:,1)) == 0)           
           y = round(linspace(min(endpoints(:,2)),max(endpoints(:,2)),numOfElems));
           x = round(linspace(min(endpoints(:,1)),max(endpoints(:,1)),numOfElems));      
       else
           k = diff(endpoints(:,2)) ./ diff(endpoints(:,1)); % the slope
           m = endpoints(1,2) - k.*endpoints(1,1); % The crossing of the y-axis           
           x = round(linspace(min(endpoints(:,1)), max(endpoints(:,1)), numOfElems));

           y = round(k.*x + m);
           % // Set any out of boundary items to the boundary
           y(y>size(L,1)) = size(L,1);
       end

       % // Convert x and y to an index for easy comparison with the image
       % // We sort them so that we are comparing the same pixels
       fittedInd = sort(sub2ind(size(L),y,x)).';
       objInd = sort(sub2ind(size(L),objy,objx));

       % Calculate the similarity. Intersect returns unique entities so we
       % use unique on fittedInd
       fitrate = numel(intersect(fittedInd,objInd)) ./ numel(unique(fittedInd));
       if (fitrate >= th)
           L(objInd) = 0;
           processed_image(objInd) = 0;
           % // figure(1),imshow(processed_image)
       end       
    end

   % // Display the result 
   figure,imshow(image);title('Original');
   figure,imshow(processed_image);title('Processed image');

这篇关于Hough变换检测和删除行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆