如何使用最佳拟合点Matlab在条形码的质心点上绘制直线

时间:2012-01-18 09:53:29

标签: matlab image-processing

这是已处理的图片,我无法增加bwareaopen(),因为它不适用于我的其他图片。

无论如何,我试图找到条形码中心点的最短点,以获得条形码中心点的直线。

实施例: 在执行质心命令后,条形码中的点彼此接近。因此,我只想得到最短的点(即条形码)并画一条直线。

所有积分都不需要加入,最合适的积分就可以。

第1步

a busy cat http://i42.tinypic.com/29ekeap.jpg

第2步

a busy cat http://i44.tinypic.com/16apts5.jpg

第3步

a busy cat http://i43.tinypic.com/1fztjm.jpg

3 个答案:

答案 0 :(得分:2)

如果您已找到中心的 x,y ,则应使用 polyfit 功能: 然后,您将找到最佳线的多项式系数。为了绘制细分,您可以采用最小和最大 x

p = polyfit(x,y,1);
xMin = min(x(:));
xMax = max(x(:));
xRange = xMin:0.01:xMax;
yRange = p(1).*xRange + p(2);
plot(xRange,yRange);

答案 1 :(得分:2)

如果您没有安德利使用的x,y元素,您可以通过分割图像并在区域上使用天真的阈值来找到它们,以避免在条形码下方包含数字。

我已经在MATLAB中破解了一个解决方案:

  1. 加载图片并使其成为二进制文件
  2. 使用bwlabel()提取所有连接的组件。
  3. 通过regionprops()获取有关每个元素的有用信息[.centroid将很好地逼近行的middel点]。
  4. 对小区域(噪音和数字)进行阈值处理
  5. 提取的x,y坐标
  6. 使用Andreys线性拟合解决方案
  7. 代码:

    set(0,'DefaultFigureWindowStyle','docked');
    close all;clear all;clc;
    Im = imread('29ekeap.jpg');
    Im=rgb2gray(Im);
    %%
    
    %Make binary
    temp = zeros(size(Im));
    temp(Im > mean(Im(:)))=1;
    Im = temp;
    
    %Visualize
    f1 = figure(1);
    imagesc(Im);colormap(gray);
    
    %Find connected components
    LabelIm = bwlabel(Im);
    
    RegionInfo = regionprops(LabelIm);
    
    %Remove background region
    RegionInfo(1) = [];
    
    %Get average area of regions
    AvgArea = mean([RegionInfo(1:end).Area]);
    
    %Vector to keep track of likely "bar elements"
    Bar = zeros(length(RegionInfo),1);
    
    %Iterate over regions, plot centroids if area is big enough
    for i=1:length(RegionInfo)
       if RegionInfo(i).Area > AvgArea 
           hold on;
           plot(RegionInfo(i).Centroid(1),RegionInfo(i).Centroid(2),'r*')
           Bar(i) = 1;
       end
    end
    
    %Extract x,y points for interpolation
    X = [RegionInfo(Bar==1).Centroid];
    X = reshape(X,2,length(X)/2);
    
    x = X(1,:);
    y = X(2,:);
    
    %Plot line according to Andrey
    p = polyfit(x,y,1);
    xMin = min(x(:));
    xMax = max(x(:));
    xRange = xMin:0.01:xMax;
    yRange = p(1).*xRange + p(2);
    plot(xRange,yRange,'LineWidth',2,'Color',[0.9 0.2 0.2]);
    

    结果是非常好的拟合线。您应该能够通过使用'p'polynomal将其扩展到最终,并在您不再遇到'1'时进行评估。

    结果:

    enter image description here

答案 2 :(得分:1)

如果您的最终目标是生成一条垂直于条形码中条形的线条并粗略地穿过条形的质心,那么我还有另一种选择供您考虑......

一个简单的解决方案是执行Hough变换以检测条形码中线条的主要方向。一旦在条形码中找到线条的角度,您所要做的就是将其旋转90度以获得垂直线的斜率。然后,整个条形码的质心可用作此线的截距。使用HOUGH中的HOUGHPEAKSImage Processing Toolbox函数,这里的代码以第1步中图像的裁剪版本开头:

img = imread('bar_code.jpg');  %# Load the image
img = im2bw(img);              %# Convert from RGB to BW

[H, theta, rho] = hough(img);  %# Perform the Hough transform
peak = houghpeaks(H);          %# Find the peak pt in the Hough transform
barAngle = theta(peak(2));     %# Find the angle of the bars
slope = -tan(pi*(barAngle + 90)/180);  %# Compute the perpendicular line slope

[y, x] = find(img);  %# Find the coordinates of all the white image points
xMean = mean(x);     %# Find the x centroid of the bar code
yMean = mean(y);     %# Find the y centroid of the bar code

xLine = 1:size(img,2);                   %# X points of perpendicular line
yLine = slope.*(xLine - xMean) + yMean;  %# Y points of perpendicular line

imshow(img);               %# Plot bar code image
hold on;                   %# Add to the plot
plot(xMean, yMean, 'r*');  %# Plot the bar code centroid
plot(xLine, yLine, 'r');   %# Plot the perpendicular line

这是最终的图像:

enter image description here