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