首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用RANSAC进行直线拟合

使用RANSAC进行直线拟合
EN

Stack Overflow用户
提问于 2017-10-05 22:56:32
回答 1查看 1.8K关注 0票数 1

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

RANSAC结果

在我对手绘图像进行矢量化的算法中,我还做了灰度缩放、图像阈值(图像二值化)和使用形态学算子的骨架化。

我正在使用MATLAB来完成我的项目。

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

代码语言:javascript
复制
% 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 
EN

回答 1

Stack Overflow用户

发布于 2017-10-20 22:04:38

我认为你的问题可能是你计算距离和/或阈值的方式,目前是1000。它可能会在任何情况下选择所有的点,并且只选择第一条或最后一条ransac线。使用RANSAC的直线拟合百分比

代码语言:javascript
复制
%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)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46588759

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档