使用RANSAC进行线路拟合

时间:2017-10-05 14:56:32

标签: matlab ransac

我正在进行图像处理项目,主要是使用图像处理技术来Vectorise手绘图像。 我在我的项目中使用RANSAC。我面临的挑战是算法没有按要求执行最佳拟合,但是 它使用任意两个随机点并绘制一条连接它们的线,如下图所示。

RANSAC结果

enter image description here

在我的Vectorise手绘图像算法中,我还进行了灰度缩放,图像阈值处理(Image Binarization), 和使用形态学运算符的骨架化。

我在项目中使用MATLAB。

以下是我到目前为止所做的代码

% Line fitting using RANSAC
[x, y] =size(skeleton_image);
point =[];
count =1; 

% figure; imshow(~data); hold on 

  for n =1:x
    for m =1:y
      if skeleton_image(n,m)==1
        point(count,1)=m;
        point(count,2)=n;
        count= count+1;
      end
    end 
  end
  data = point';
number = size(data,2); % Total number of points
X = 1:number;
iter=100; num=2; thresh = 1000;count_inlines=103; best_count=0; best_line=[];

for i=1:iter
% Randomly select 2 points
  ind = randi(number,num); % randperm(number,num);
  rnd_points= data(:,ind);
% Fitting line
  Gradient = (rnd_points(2,2)-rnd_points(2,1))/(rnd_points(1,2)-rnd_points(1,1));
  Constant = rnd_points(2,1)-Gradient*rnd_points(1,1);
  Line = Gradient*X+Constant; [j,k]=size(Line);
% How many pixels are in the line?
  for i=1:number 

    Distance = sqrt((Line(:,i)-data(1,i)).^2)+(Line(:,i)-data(2,i)).^2); 

  if Distance<=thresh
    inlines = data(:,i);
    count_inlines=countinlines+1;
      best_line=Line; 
end 

1 个答案:

答案 0 :(得分:0)

我认为您的问题可能在于计算当前距离和/或当前1000的阈值。它可能会选择所有点,只需选择第一个或最后一个ransac线。     %使用RANSAC进行线拟合

%create skeleton_image objects
skeleton_image = zeros(50,50);

% draw a circle
circle_center = [15,15];
radius = 6;
for i=1:50
  for j = 1:50
    if  abs( radius - sqrt( (i-circle_center(1))^2 + (j-circle_center(2))^2 ) ) <0.5 % < controls the thickness of the circle
      skeleton_image(i,j) = 1;

    endif
  end
end 

% draw a line
grad=0.5;
dy = 20;
for i=10:50
  skeleton_image(ceil(dy + grad*i),i)=1;  
  if (i < 50) 
    skeleton_image(ceil(dy + grad*i)+1,i)=1;  
  endif
end

% a handful of random points to make it more realistic
skeleton_image(20,22)=1;  
skeleton_image(30,7)=1; 
skeleton_image(18,45)=1; 
skeleton_image(10,10)=1; 
skeleton_image(20,23)=1;  
skeleton_image(31,6)=1; 
skeleton_image(19,45)=1; 
skeleton_image(9,13)=1; 
skeleton_image(20,24)=1;  
skeleton_image(31,5)=1; 
skeleton_image(18,46)=1; 

% [x, y] =size(skeleton_image);
x = 50;
y = 50;
points =[];
count =1; 

  for n =1:x
    for m =1:y
      if skeleton_image(n,m)==1
        points(count,1)=m;
        points(count,2)=n;
        count= count+1;
      end
    end 
  end



best_line = [];
best_count = 0;
line_point_list = [];
% how close the pixel has to be to the line to be accepted
threshold = 1;

% how many samples are taken
steps = 10;

for i=1:steps
  % pick two points 
   ind1 = randi(number,1);
   ind2 = randi(number,1);
   point1 = points(ind1,:);
   point2 = points(ind2,:);

   %auxiliaries
   line = [point1;point2];
   lpl = []; %line_point_list
   count_i = 0;

   if point1 != point2
     vector1 = point2-point1;
     % unit vector
     vector1_normalized = vector1 ./ norm(vector1);
     % normal direction of the line
     normal_of_vector1 = [vector1_normalized(2), -vector1_normalized(1)];

     % loop over points
     for j = 1:size(points)
       % calculate distance
       normal_of_vector1;
       vector2 = points(j,:) - point1;
       distance = abs(dot(vector2, normal_of_vector1));
       if ( distance < threshold )
         count_i +=1;
         lpl(count_i,:) = points(j,:);
       endif
     end 
   endif
   if ( count_i > best_count)
     best_count = count_i;
     best_line = line;
     line_point_list = lpl;
   endif
end
 %best_c
 %best_l
 %line_point_list


% draw found points 
for i=1:size(line_point_list)
  skeleton_image(line_point_list(i,2),line_point_list(i,1) ) = 0.25;
end

%visualize
figure(1)
imshow(skeleton_image)