Drawing auto polyline around tif image

2 次查看(过去 30 天)
Hello,
First of all, I am so new to image analysis on matlab and I have a problem that I could not solve. I have been working on a tif image to create a poly line around a region of interest. My code is working for some of the images, but I also get weird polylines in other samples. I am wondering if anyone can help me to work it again? The below image shows the weird poly lines, which I think it is because of the contrast in the image. Basically I want to draw a poly line covering the region where I have the data (I need to exclude top black region, but need to cover below gray and black+gary region). I have also added the original tif image and my code.
%% Extract the contour from the BC image
clc
fontSize = 25;
% Create initial image.
grayImage = imread('MAP_BC.tif');
% check the exposure
figure
subplot(1, 2, 1);
imshow(grayImage, []);
title('Band Contrast')
impixelinfo
subplot(1, 2, 2);
imhist(grayImage);
grid on;
title('Histogram of Band Contrast')
lowThreshold = 50; % for top part
highThreshold = 153; % for bottom part
binaryImage = grayImage >= lowThreshold;
binaryImage = bwareafilt(binaryImage, 1);
boundary = bwboundaries(binaryImage, 8,"noholes");
xb = boundary{1}(:, 2);
yb = boundary{1}(:, 1);
subplot(1, 2, 1);
hold on;
plot(xb, yb, 'r-', 'LineWidth', 1);

回答(2 个)

Moksh
Moksh 2023-8-29
Hi Huseyin,
As per my understanding the thresholding technique you are using is catching the white noise elements above your region of interest and that is why you are getting those unwanted lines.
For resolving this you can segment the image to get the required region of interest, and then generate a binary image. You can then pass this binary image directly into the 'bwboundary' function and generate boundary coordinates. For segmenting the image you can use the 'activecontour' function in MATLAB. You can just add this subsection within your code as follows:
grayImage = imread("MAP_BC.tif");
figure;
subplot(1, 2, 1);
imshow(grayImage);
% Get the segmented image
segmentedImage = segment(grayImage);
subplot(1, 2, 2);
imshow(segmentedImage);
% Generating boundary points from the segmented image
boundary = bwboundaries(segmentedImage, 8,"noholes");
xb = boundary{1}(:, 2);
yb = boundary{1}(:, 1);
subplot(1, 2, 1);
hold on;
plot(xb, yb, 'r-', 'LineWidth', 1);
% Code for segmenting the image in foreground and background
function [bw] = segment(imageFile)
imageFile = imageFile(:,:,1);
mask_width = 1;
border_width = 1;
imageFile = padarray(imageFile, [border_width, border_width], 0);
mask = zeros(size(imageFile));
mask(mask_width:end - mask_width, mask_width:end - mask_width) = 1;
small_image_itter = 3500;
bw = activecontour(imageFile, mask, small_image_itter, 'Chan-Vese', 'SmoothFactor', 0.95);
end
You can alter the 'small_image_itter' variable to alter the sharpness of the segmented boundary. This code generated the following output
Please refer to the following documentation for further understanding of 'activecontour', 'bwboundaries' functions and the segmentation code
Hope this helps!

Image Analyst
Image Analyst 2023-8-29
Not sure how I missed this when it was first posted but here is one way I'd do it.
%% Extract the contour from the BC image
clc
fontSize = 25;
% Create initial image.
grayImage = imread('MAP_BC.tif');
% check the exposure
figure
subplot(2, 2, 1);
imshow(grayImage, []);
title('Band Contrast')
impixelinfo
subplot(2, 2, 2);
imhist(grayImage);
grid on;
title('Histogram of Band Contrast')
% Binarize the image.
lowThreshold = 100; % for top part
highThreshold = 255; % for bottom part
% Interactively and visually set a threshold on a gray scale image.
% https://www.mathworks.com/matlabcentral/fileexchange/29372-thresholding-an-image?s_tid=srchtitle
% [lowThreshold, highThreshold] = threshold(lowThreshold, highThreshold, grayImage);
binaryImage = grayImage >= lowThreshold & grayImage <= highThreshold;
% Fill holes.
binaryImage = imfill(binaryImage, 'holes');
% Take largest blob only.
binaryImage = bwareafilt(binaryImage, 1);
subplot(2, 2, 3);
imshow(binaryImage, []);
title('Binary Image')
% Find boundaries
boundary = bwboundaries(binaryImage, 8,"noholes");
xb = boundary{1}(:, 2);
yb = boundary{1}(:, 1);
% Plot over original image.
subplot(2, 2, 1);
hold on;
plot(xb, yb, 'r-', 'LineWidth', 1);
If you want to make the boundary smoother you can call imclose. If you need the blob edges to touch the edge of the image, then you can just find the top rows by scanning the binary image column by column. Let me know if you need help with that.
  2 个评论
Huseyin Hizli
Huseyin Hizli 2023-10-6
Hi sorry for my really late reply due to some issues.
I can get the same image in my code, but what I want is something like in the below picture where green lines encircles. Basically, the top black region should not be in the image after binarization.
Also, i am wondering if there is a way to get a polyline that is only showing the black area in purple square in below image.
Image Analyst
Image Analyst 2023-10-6
Try to get it by thresholding. If you can't then try stdfilt and threshold that. It looks like the local standard deviation might be different in that part.
If you can't figure it out, then write me back.

请先登录,再进行评论。

Community Treasure Hunt

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

Start Hunting!

Translated by