Clear Filters
Clear Filters

Drawing auto polyline around tif image

5 views (last 30 days)
Huseyin Hizli
Huseyin Hizli on 21 Dec 2022
Commented: Image Analyst on 6 Oct 2023
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);

Answers (2)

Moksh
Moksh on 29 Aug 2023
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 on 29 Aug 2023
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 Comments
Huseyin Hizli
Huseyin Hizli on 6 Oct 2023
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 on 6 Oct 2023
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.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!