how to do hysteresis thesholding on canny edge detection?

18 次查看(过去 30 天)
hi partner, I need help here, I do canny edge detection on a wood image but in the hsteresis process a lot of edges are lost while in the Non-Maximum Suppression process the resulting edge has a lot of noise. can a partner help me to get the edge of the circle that is in the wood in the hysteresis process without any noise? what I need is the edges of the circles in the wood
clear all;
clc;
I = imread ('WhatsAppImage.jpeg');
figure, imshow(I);
I = rgb2gray(I);
I = double (I);
%Thresholding
T_Low = 0.075;
T_High = 0.175;
%Gaussian
B = [2, 4, 5, 4, 2; 4, 9, 12, 9, 4;5, 12, 15, 12, 5;4, 9, 12, 9, 4;2, 4, 5, 4, 2 ];
B = 1/159.* B;
A=conv2(I, B, 'same');
%Horizontal, vertical
KGx = [-1, 0, 1; -2, 0, 2; -1, 0, 1];
KGy = [1, 2, 1; 0, 0, 0; -1, -2, -1];
Filtered_X = conv2(A, KGx, 'same');
Filtered_Y = conv2(A, KGy, 'same');
arah = atan2 (Filtered_Y, Filtered_X);
arah = arah*180/pi;
pan=size(A,1);
leb=size(A,2);
for i=1:pan
for j=1:leb
if (arah(i,j)<0)
arah(i,j)=360+arah(i,j);
end;
end;
end;
arah2=zeros(pan, leb);
for i = 1 : pan
for j = 1 : leb
if ((arah(i, j) >= 0 ) && (arah(i, j) < 22.5) || (arah(i, j) >= 157.5) && (arah(i, j) < 202.5) || (arah(i, j) >= 337.5) && (arah(i, j) <= 360))
arah2(i, j) = 0;
elseif ((arah(i, j) >= 22.5) && (arah(i, j) < 67.5) || (arah(i, j) >= 202.5) && (arah(i, j) < 247.5))
arah2(i, j) = 45;
elseif ((arah(i, j) >= 67.5 && arah(i, j) < 112.5) || (arah(i, j) >= 247.5 && arah(i, j) < 292.5))
arah2(i, j) = 90;
elseif ((arah(i, j) >= 112.5 && arah(i, j) < 157.5) || (arah(i, j) >= 292.5 && arah(i, j) < 337.5))
arah2(i, j) = 135;
end;
end;
end;
figure, imagesc(arah2); colorbar;
%Magnitude
magnitude = (Filtered_X.^2) + (Filtered_Y.^2);
magnitude2 = sqrt(magnitude);
BW = zeros (pan, leb);
%Non-Maximum Supression
for i=2:pan-1
for j=2:leb-1
if (arah2(i,j)==0)
BW(i,j) = (magnitude2(i,j) == max([magnitude2(i,j), magnitude2(i,j+1), magnitude2(i,j-1)]));
elseif (arah2(i,j)==45)
BW(i,j) = (magnitude2(i,j) == max([magnitude2(i,j), magnitude2(i+1,j-1), magnitude2(i-1,j+1)]));
elseif (arah2(i,j)==90)
BW(i,j) = (magnitude2(i,j) == max([magnitude2(i,j), magnitude2(i+1,j), magnitude2(i-1,j)]));
elseif (arah2(i,j)==135)
BW(i,j) = (magnitude2(i,j) == max([magnitude2(i,j), magnitude2(i+1,j+1), magnitude2(i-1,j-1)]));
end;
end;
end;
BW = BW.*magnitude2;
figure, imshow(BW);
%Hysteresis Thresholding
T_Low = T_Low * max(max(BW));
T_High = T_High * max(max(BW));
T_res = zeros (pan, leb);
for i = 1 : pan
for j = 1 : leb
if (BW(i, j) < T_Low)
T_res(i, j) = 0;
elseif (BW(i, j) > T_High)
T_res(i, j) = 1;
elseif ( BW(i+1,j)>T_High || BW(i-1,j)>T_High || BW(i,j+1)>T_High || BW(i,j-1)>T_High || BW(i-1, j-1)>T_High || BW(i-1, j+1)>T_High || BW(i+1, j+1)>T_High || BW(i+1, j-1)>T_High)
T_res(i,j) = 1;
end;
end;
end;
edge_final = uint8(T_res.*255);
figure, imshow(edge_final);

回答(1 个)

Suraj Kumar
Suraj Kumar 2024-8-28
Hi Fika,
Based on my understanding, you want to detect the edges of an image and extract them without any noise. You can go through the following steps and the attached code snippets to achieve the desired results:
1. Read and preprocess the image by converting it into grayscale using ‘rgb2gray’ function.
% Read the image
image = imread('img.jpeg');
grayImage = rgb2gray(image);
2. Apply a gaussian filter using imgaussfiltfunction, which is essential for smoothing the image for effective edge detection. Compute the gradients in the x and y directions using 'sobel operator .
% Apply Gaussian filter
blurredImage = imgaussfilt(grayImage, 1.4);
[Gx, Gy] = imgradientxy(blurredImage, 'sobel');
magnitude = sqrt(Gx.^2 + Gy.^2);
direction = atan2(Gy, Gx);
3. Suppress the non-maximum pixels for thinning the edges by comparing each pixel’s gradient magnitude with its neighbours.
% Non-Maximum Suppression
nms = zeros(size(magnitude));
[rows, cols] = size(magnitude);
for i = 2:rows-1
for j = 2:cols-1
angle = direction(i, j) * 180 / pi;
angle = mod(angle + 180, 180);
if ((angle >= 0 && angle < 22.5) || (angle >= 157.5 && angle <= 180))
if (magnitude(i, j) >= magnitude(i, j-1) && magnitude(i, j) >= magnitude(i, j+1))
nms(i, j) = magnitude(i, j);
end
elseif (angle >= 22.5 && angle < 67.5)
if (magnitude(i, j) >= magnitude(i-1, j+1) && magnitude(i, j) >= magnitude(i+1, j-1))
nms(i, j) = magnitude(i, j);
end
elseif (angle >= 67.5 && angle < 112.5)
if (magnitude(i, j) >= magnitude(i-1, j) && magnitude(i, j) >= magnitude(i+1, j))
nms(i, j) = magnitude(i, j);
end
elseif (angle >= 112.5 && angle < 157.5)
if (magnitude(i, j) >= magnitude(i-1, j-1) && magnitude(i, j) >= magnitude(i+1, j+1))
nms(i, j) = magnitude(i, j);
end
end
end
end
4. Apply double thresholding to classify pixels as strong edges, weak edges, or non-edges. This helps in distinguishing between significant edges and noise.
highThreshold = max(nms(:)) * 0.1;
lowThreshold = highThreshold * 0.5;
strongEdges = nms >= highThreshold;
weakEdges = (nms >= lowThreshold) & (nms < highThreshold);
5. Track the edges by starting from strong edges then to connected weak edges to preserve important edges while reducing noise. Then display the results.
% Edge tracking by hysteresis
edges = zeros(size(nms));
for i = 2:rows-1
for j = 2:cols-1
if strongEdges(i, j)
edges(i, j) = 1;
elseif weakEdges(i, j)
if any(any(strongEdges(i-1:i+1, j-1:j+1)))
edges(i, j) = 1;
end
end
end
end
You can refer to the output below for a better understanding:
For more information, kindly refer to the documentation links below:
I hope this works for you!

Community Treasure Hunt

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

Start Hunting!

Translated by