Is there a way to batch find streamline equations from an image?

9 次查看(过去 30 天)
I would like to use image processing to fit splines/curves to the blue lines present in the image above. The code below has gotten me to the point of having isolated the lines, but I would like to write code that gives a best fit polynomial for each line. I've looked into using curve fitter, but could only figure out how to use it to fit all data presented. Any direction would be appreciated.
img_filename = 'circle.jpg';
rgb = imread(img_filename); % open image
hsv = rgb2hsv(rgb); % convert to HSV
h_channel = hsv(:,:,1); % isolate hue channel
BW1 = imbinarize(h_channel); % Threshold image - global threshold - convert to black and white
% Open mask with disk - generated by Image Segmenter app
% Fills in some of the holes caused by the gridlines
radius = 6;
decomposition = 8;
se = strel('disk', radius, decomposition);
image_mask = imopen(BW1, se);
edges = edge(image_mask, 'Sobel'); % edge detection
% different edge detection methods available:
% Sobel (default), Canny, Prewitt, Roberts, log, zerocross, Canny, approxcanny
figure(1);
% Figure to show the image cleanup process
subplot(2,2,1); imshow(rgb); title('1- Original');
subplot(2,2,2); imshow(h_channel); title('2- Hue Channel')
subplot(2,2,3); imshow(BW1); title('3 - Binarized')
subplot(2,2,4); imshow(image_mask); title('4 - Opened Mask')
figure(2);
% Figure to show the final edge detection
imshow(edges);
[row,col] = find(edges==1);

回答(2 个)

Antoni Garcia-Herreros
I would suggest looking into the matlab documentation of bwskel and bwconncomp. Something like this should work, you can probably play arround with the polyfit order or even use a spline interpolant.
% Smooth BW image
windowSize = 51;
kernel = ones(windowSize) / windowSize ^ 2;
A=conv2(single(BW1), kernel, 'same');
BW2=imbinarize(A); % Re binarize
BWskel = bwskel(BW2); % Skeletonize the BW image
CC = bwconncomp( BWskel ,8); % Get the connected pixels
for i=1:CC.NumObjects %Get an array with the length of all arrays found
l(i)=length(CC.PixelIdxList{i});
end
lfilt=find(l>500); %Filter the chains by a minimum length to discard artifacts
imshow(BW2)
xx=2200:5500;
hold on
for i=1:length(lfilt)
a=CC.PixelIdxList{lfilt(i)};
[rr,cc] = ind2sub(CC.ImageSize,a);
p = polyfit(cc,rr,9); % Fit polynamomial 9th order
yy = polyval(p,xx);
plot(xx,yy)
end
  1 个评论
DGM
DGM 2023-3-16
As an add-on, maybe consider correcting for perspective first; otherwise, there is no reference for the curves.
img_filename = 'image.jpeg';
rgb = imread(img_filename); % open image
% these are the coordinates of the box corners
% you can get these using getpts() or impixelinfo() or datatips
boxm = [378 202; % [x y]
330 3499;
5511 3363;
5383 218];
% assert that this is where they're supposed to be
% any coordinates that define a rectangle
boxf = [350 200; % [x y]
350 3450;
5450 3450;
5450 200];
% fix the perspective
TF = fitgeotrans(boxm,boxf,'projective');
outview = imref2d(size(rgb));
rgb = imwarp(rgb,TF,'fillvalues',255,'outputview',outview);
imshow(rgb)

请先登录,再进行评论。


Image Analyst
Image Analyst 2023-3-16
The blue lines are not polynomials. I'd just deal with them numerically and use spline. Why would you want a polynomial formula for each line anyway? What would you do with that assuming you had the polynomial coefficients?
Your image also has bad lens shading or lighting nonuniformities that should be corrected for, though using imopen does do that to some degree. I've attached background correction demos.

类别

Help CenterFile Exchange 中查找有关 Images 的更多信息

产品


版本

R2022a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by