two-dimensional Otsu's method

3 visualizzazioni (ultimi 30 giorni)
Harsha
Harsha il 29 Gen 2016
Commentato: Image Analyst il 13 Nov 2020
I am trying to implement 2D Otsu segmentation method, but i am facing problem in my code. in 2D otsu the gray-level value of each pixel as well as the average value of its immediate neighborhood is studied so that the binarization results are greatly improved. I am attaching code,but it is not working and also hyperlink http://en.wikipedia.org/wiki/Otsu%27s_method
function inputs and output:
%hists is a 256\times 256 2D-histogram of grayscale value and neighborhood average grayscale value pair.
%total is the number of pairs in the given image.
%threshold is the threshold obtained.
function threshold = 2D_otsu(hists, total)
maximum = 0.0;
threshold = 0;
helperVec = 0:255;
mu_t0 = sum(sum(repmat(helperVec',1,256).*hists));
mu_t1 = sum(sum(repmat(helperVec,256,1).*hists));
p_0 = zeros(256);
mu_i = p_0;
mu_j = p_0;
for ii = 1:256
for jj = 1:256
if jj == 1
if ii == 1
p_0(1,1) = hists(1,1);
else
p_0(ii,1) = p_0(ii-1,1) + hists(ii,1);
mu_i(ii,1) = mu_i(ii-1,1)+(ii-1)*hists(ii,1);
mu_j(ii,1) = mu_j(ii-1,1);
end
else
p_0(ii,jj) = p_0(ii,jj-1)+p_0(ii-1,jj)-p_0(ii-1,jj-1)+hists(ii,jj);
mu_i(ii,jj) = mu_i(ii,jj-1)+mu_i(ii-1,jj)-mu_i(ii-1,jj-1)+(ii-1)*hists(ii,jj);
mu_j(ii,jj) = mu_j(ii,jj-1)+mu_j(ii-1,jj)-mu_j(ii-1,jj-1)+(jj-1)*hists(ii,jj);
end
if (p_0(ii,jj) == 0)
continue;
end
if (p_0(ii,jj) == total)
break;
end
tr = ((mu_i(ii,jj)-p_0(ii,jj)*mu_t0)^2 + (mu_j(ii,jj)-p_0(ii,jj)*mu_t0)^2)/(p_0(ii,jj)*(1-p_0(ii,jj)));
if ( tr >= maximum )
threshold = ii;
maximum = tr;
end
end
end
  3 Commenti
Harsha
Harsha il 29 Gen 2016
Modificato: Geoff Hayes il 29 Gen 2016
Hi Geoff Hayes thank you for your reply, I want to segment lung using 2d Otsu method. Because 2d Otsu is improved one compare to 1D Otsu (graythresh() and multithresh()),2D Otsu threshold by averaging image. I am referring : https://en.wikipedia.org/wiki/Otsu's_method
Here I am attaching ZIP file contain test.m (main file) Otsu_2D(2D otsu logic) 1.tif(image)
Following Error:-
Attempted to access p_0(0,2); index must be a positive integer or logical.
Error in otsu_2D (line 26)
p_0(ii,jj) = p_0(ii,jj-1)+p_0(ii-1,jj)-p_0(ii-1,jj-1)+hists(ii,jj);
Error in t2 (line 56)
thresh = otsu_2D(hist2d, total) %threshold obtained 2D Otsu
Prabhu Bevinamarad
Prabhu Bevinamarad il 13 Nov 2020
Hi,
I am new to Matlab. I wanted to apply two-dimensional Otsu's method for thresholding. I am not getting how to find hists i.e. 2D-histogram of grayscale value and neighborhood average grayscale value pair and total is the number of pairs in the given image which are passed as a parameters for otsu_2D function.Can anybody suggest which functions are used.
Thank you

Accedi per commentare.

Risposta accettata

Geoff Hayes
Geoff Hayes il 29 Gen 2016
pramod - the error message is telling you that the code is trying to access an element within your matrix using an index that is zero. I realize that you are considering the neighbourhood surrounding each cell within your 256x256 matrix, but your code will have to account for the edge cases when subtracting one from the index leads to a zero which "falls" outside of your matrix. You will have to guard against this code as follows
for ii = 1:256
for jj = 1:256
if jj == 1
if ii == 1
p_0(1,1) = hists(1,1);
else
p_0(ii,1) = p_0(ii-1,1) + hists(ii,1);
mu_i(ii,1) = mu_i(ii-1,1)+(ii-1)*hists(ii,1);
mu_j(ii,1) = mu_j(ii-1,1);
end
else
% here is the new code ***** guard against ii==1
if ii==1
p_0(ii,jj) = p_0(ii,jj-1)+hists(ii,jj);
mu_i(ii,jj) = mu_i(ii,jj-1)+(ii-1)*hists(ii,jj);
mu_j(ii,jj) = mu_j(ii,jj-1)+(jj-1)*hists(ii,jj);
else
p_0(ii,jj) = p_0(ii,jj-1)+p_0(ii-1,jj)-p_0(ii-1,jj-1)+hists(ii,jj);
mu_i(ii,jj) = mu_i(ii,jj-1)+mu_i(ii-1,jj)-mu_i(ii-1,jj-1)+(ii-1)*hists(ii,jj);
mu_j(ii,jj) = mu_j(ii,jj-1)+mu_j(ii-1,jj)-mu_j(ii-1,jj-1)+(jj-1)*hists(ii,jj);
end
end
I don't know for sure if the above is correct but it will guard against the case where jj is greater than one and ii is equal to one (the pattern is similar to what is already there for the case where jj is one and ii is one). A note should be added to the Wikipedia article indicating that there is a bug with the code.
ImageAnalyst would have a better idea as to whether the above makes sense or not.
And, rather than posting a binary zip file which some of us may be reluctant to open, just attach each file individually (since there are just three).
  10 Commenti
Harsha
Harsha il 4 Dic 2016
hists is an 2d-histogram of image with size M×N can be represented by a 2D gray level intensity function f(x, y). The value of f(x, y) is the gray level, ranging from 0 to L-1, where L is the number of distinct gray levels. In a 2D thresholding method, the gray level of a pixel and its local average gray level are both used. The local average gray level is also divided into the same L values, let g(x, y) be the function of the local average gray level.f(x,y) is an input image and g(x,y) average gray level of input image. total is the number of pixels in the input image(i.e M x N).
Image Analyst
Image Analyst il 13 Nov 2020
No idea what this means exactly but as far as I can tell, it's this:
% Read in input image f(x,y) with L = 256 gray levels:
fxy = imread('cameraman.tif');
% No idea what "The local average gray level is also divided into the same L values" means,
% but to get an image where each pixel is the average in a square window around the pixel, do thi
windowWidth = 3; % Whatever you want.
kernel = ones(windowWidth, windowWidth) / windowWidth^2;
gxy = imfilter(fxy, kernel);
% Now get the total number of pixels in fxy and gxy:
total = numel(fxy)
Note that images are indexed fxy(y, x), which is fxy(row, column), and NOT as fxy(x, y).
But gxy is simply a blurred input image -- the local average. It is not a 2-D histogram. I'm wondering if he wants 256 histograms, one for the neighbors of each pixel (not including the pixel itself), like
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 = 18;
fprintf('Beginning to run %s.m ...\n', mfilename);
echo off;
%===============================================================================
% Get the name of the demo image the user wants to use.
% Let's let the user select from a list of all the demo images that ship with the Image Processing Toolbox.
folder = fileparts(which('cameraman.tif')); % Determine where demo folder is (works with all versions).
% Demo images have extensions of TIF, PNG, and JPG. Get a list of all of them.
imageFiles = [dir(fullfile(folder,'*.TIF')); dir(fullfile(folder,'*.PNG')); dir(fullfile(folder,'*.jpg'))];
for k = 1 : length(imageFiles)
% fprintf('%d: %s\n', k, files(k).name);
[~, baseFileName, extension] = fileparts(imageFiles(k).name);
ca{k} = [baseFileName, extension];
end
% Sort the base file names alphabetically.
[ca, sortOrder] = sort(ca);
imageFiles = imageFiles(sortOrder);
button = menu('Use which gray scale demo image?', ca); % Display all image file names in a popup menu.
% Get the base filename.
baseFileName = imageFiles(button).name; % Assign the one on the button that they clicked on.
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
grayImage = imread(fullFileName);
[rows, columns, numberOfColorChannels] = size(grayImage);
if numberOfColorChannels == 3
grayImage = rgb2gray(grayImage);
end
subplot(2, 1, 1);
imshow(grayImage);
caption = sprintf('Original gray scale image : %s', baseFileName);
title('Original gray scale image');
drawnow;
% Intantiate 2-D histogram
hist2d = zeros(256, 256);
for col = 2 : columns-1
fprintf('Processing column %d of original image...\n', col);
for row = 2 : rows-1
% Get 3x3 subimage, except for center pixel, so that's 8 pixels.
subImage = [grayImage(row-1, col-1);...
grayImage(row-1, col);...
grayImage(row-1, col+1);...
grayImage(row, col-1);...
grayImage(row, col+1);...
grayImage(row+1, col+1);...
grayImage(row+1, col+1);...
grayImage(row+1, col+1)];
% Get the gray levle of the center pixel
centerGL = grayImage(row, col) + 1; % Add 1 so we don't get 0 because matrices can't have a zeroeth row or column.
for k = 1 : length(subImage)
% Get this gray level
thisGL = subImage(k) + 1; % Add 1 so we don't get 0 because matrices can't have a zeroeth row or column.
% Increment the histogram at the column for the center pixel's gray level
hist2d(centerGL, thisGL) = hist2d(centerGL, thisGL) + 1;
end
end
end
% Display the 2-D histogram
subplot(2, 1, 2);
imshow(hist2d, [], 'Colormap', jet(256));
title('2D histogram');
colorbar

Accedi per commentare.

Più risposte (1)

Harsha
Harsha il 4 Dic 2016
hists is an 2d-histogram of image with size M×N can be represented by a 2D gray level intensity function f(x, y). The value of f(x, y) is the gray level, ranging from 0 to L-1, where L is the number of distinct gray levels. In a 2D thresholding method, the gray level of a pixel and its local average gray level are both used. The local average gray level is also divided into the same L values, let g(x, y) be the function of the local average gray level.f(x,y) is an input image and g(x,y) average gray level of input image. total is the number of pixels in the input image(i.e M x N).
  5 Commenti
Image Analyst
Image Analyst il 23 Feb 2018
Madhava, I don't understand what you said.
Please elaborate after reading this link.
MAS
MAS il 5 Apr 2018
It works absolutely fine for two clusters. Any suggestions to update it for handling multi-level thresholding!?

Accedi per commentare.

Tag

Community Treasure Hunt

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

Start Hunting!

Translated by