フィルターのクリア

Thresholding of images gone wrong

11 ビュー (過去 30 日間)
Gucci
Gucci 2022 年 4 月 28 日
コメント済み: Image Analyst 2022 年 5 月 3 日
Hello,
I have attached a small file of 3 images...
When I run the following code of the function 'graythresh', I end up with a strange binary image that also changes part of the background to 1, I am not sure how to use graythresh to select the threshold level efficiently...
%%
clc;
clear;
close all;
load('doubleBeadSample');
A=doubleBeadSample(:,:,1);
%% Size of Matrix A
[r,c]=size(A);
%% Otsu threshold
B=im2gray(A);
%figure;
temp=graythresh(B);
bin_im=im2bw(B,temp);
%%
figure;
subplot(1,2,1)
imagesc(doubleBeadSample(:,:,1)); %
title(' frame');
subplot(1,2,2)
imagesc(bin_im); % image after thresholding
title(' frame with threshold');
  1 件のコメント
Gucci
Gucci 2022 年 4 月 28 日
@Image Analyst @Image.Processor is it possible to see where I went wrong here? This is the output image I am getting on the right..

サインインしてコメントする。

採用された回答

Image Analyst
Image Analyst 2022 年 4 月 29 日
Try this:
% Demo by Image Analyst
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 22;
markerSize = 40;
%--------------------------------------------------------------------------------------------------------
% READ IN IMAGE
folder = pwd;
baseFileName = 'doubleBeadSample.mat';
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% The file doesn't exist -- didn't find it there in that folder.
% Check the entire search path (other folders) for the file by stripping off the folder.
fullFileNameOnSearchPath = baseFileName; % No path this time.
if ~exist(fullFileNameOnSearchPath, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
s = load(fullFileName)
rgbImage = s.doubleBeadSample;
% Get the dimensions of the image.
% numberOfColorChannels should be = 1 for a gray scale image, and 3 for an RGB color image.
[rows, columns, numberOfColorChannels] = size(rgbImage)
if numberOfColorChannels > 1
% It's not really gray scale like we expected - it's color.
fprintf('It is not really gray scale like we expected - it is color\n');
% Extract the blue channel.
grayImage = rgbImage(:, :, 3);
else
grayImage = rgbImage;
end
%--------------------------------------------------------------------------------------------------------
% Display the image.
subplot(2, 2, 1);
imshow(grayImage);
impixelinfo;
axis('on', 'image');
title('Original Gray Scale Image', 'FontSize', fontSize, 'Interpreter', 'None');
% Maximize window.
g = gcf;
g.WindowState = 'maximized';
drawnow;
% Display histogram.
subplot(2, 2, 2);
imhist(grayImage);
grid on;
drawnow;
title('Histogram of Image', 'FontSize', fontSize, 'Interpreter', 'None');
%--------------------------------------------------------------------------------------------------------
% Binarize the image to get a mask.
lowThreshold = 4000;
highThreshold = intmax("int16")
% threshold(lowThreshold, highThreshold, grayImage);
mask = grayImage >= lowThreshold & grayImage <= highThreshold;
% Put red threshold line on histogram so they know where it was thresholded at.
xline(lowThreshold, 'Color', 'r', 'LineWidth', 2)
% Delete blobs touching border.
mask = imclearborder(mask);
mask = imfill(mask, 'holes');
% Take at most 2 blobs.
mask = bwareafilt(mask, 2);
% Display mask image.
subplot(2, 2, 3);
imshow(mask);
hold on;
impixelinfo;
axis('on', 'image');
drawnow;
title('Mask, a Binary Image', 'FontSize', fontSize, 'Interpreter', 'None');
% Plot the borders of all the blobs in the overlay above the original grayscale image
% using the coordinates returned by bwboundaries().
% bwboundaries() returns a cell array, where each cell contains the row/column coordinates for an object in the image.
subplot(2,2,4);
imshow(grayImage, []); % Optional : show the original image again. Or you can leave the binary image showing if you want.
% Here is where we actually get the boundaries for each blob.
boundaries = bwboundaries(mask);
% boundaries is a cell array - one cell for each blob.
% In each cell is an N-by-2 list of coordinates in a (row, column) format. Note: NOT (x,y).
% Column 1 is rows, or y. Column 2 is columns, or x.
numberOfBoundaries = size(boundaries, 1); % Count the boundaries so we can use it in our for loop
% Here is where we actually plot the boundaries of each blob in the overlay.
hold on; % Don't let boundaries blow away the displayed image.
for k = 1 : numberOfBoundaries
thisBoundary = boundaries{k}; % Get boundary for this specific blob.
x = thisBoundary(:,2); % Column 2 is the columns, which is x.
y = thisBoundary(:,1); % Column 1 is the rows, which is y.
plot(x, y, 'r-', 'LineWidth', 2); % Plot boundary in red.
end
hold off;
caption = sprintf('%d Outlines, from bwboundaries()', numberOfBoundaries);
title(caption, 'FontSize', fontSize);
axis('on', 'image'); % Make sure image is not artificially stretched because of screen's aspect ratio.
% Get all the blob properties. Can only pass in originalImage in version R2008a and later.
props = regionprops(mask, grayImage, 'Area', 'Centroid', 'WeightedCentroid');
allAreas = [props.Area]
centroids = vertcat(props.Centroid)
weightedCentroid = vertcat(props.WeightedCentroid)
% Plot centroids with a red dot
hold on;
plot(centroids(:, 1), centroids(:, 2), 'r.', 'MarkerSize', 50);
% Plot a yellow line between them.
plot(centroids(:, 1), centroids(:, 2), 'y-', 'LineWidth', 4);
hold off;
deltas = diff(centroids, 1)
distance = sqrt(deltas(1) .^ 2 + deltas(2) .^ 2)
% Tell the user
message = sprintf('The distance between centroids is %.1f pixels', distance);
title(message, 'FontSize', fontSize);
uiwait(helpdlg(message))
  11 件のコメント
Gucci
Gucci 2022 年 5 月 3 日
編集済み: Gucci 2022 年 5 月 3 日
@Image Analyst Thank you, I understand your method above for simple matrices to get the separation,
however the complicated bookeeping that you said is unfortunately my task with this, to perform the same operation as the normal code so that I can measure the error between the 2..
I have tried but keep failing to convert the values I get for the 3 blobs, into 2 positions and then find the distance between object 1 and object 2, which should be equivalent to that of the normal code..
Image Analyst
Image Analyst 2022 年 5 月 3 日
I showed you how to do it with a simple 1-D example, and I showed you how to do it with images (attached again) so you should be able to figure it out. I will be traveling for the next 4 days and probably won't be able to answer any but the simplest of questions from people (not so easy to do code on my iPad which is the only computer I'm taking with me). Plus I'll be busy all day. But it's not hard and I'm sure by Saturday you'll have it all figured out.

サインインしてコメントする。

その他の回答 (1 件)

Image Analyst
Image Analyst 2022 年 4 月 28 日
What parts of the image would you want to be foreground and background?
I think it's best to look at the image in grayscale.
See my interactive threshold in my File Exchange:

カテゴリ

Help Center および File ExchangeExplore and Edit Images with Image Viewer App についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by