Generating histogram of a gradient image: histogram bar shows a white blank space within a histogram bar

I have generated a sobel gradient map of an image and now i have to generate the histogram of that gradient map. i did this
[rows, columns, numberOfColorBands] = size(sobelImage);
[pixelCounts, channels] = imhist(sobelImage, 256);
bar(channels, pixelCounts);
xlim([0 255]);
drawnow();
The sobel image is coming good, there is no error. but when i generate the histogram, i can only see a the color scale and a white blank space. can you please tell me how to work through this? and i am asked to only keep certain percentage of pixels from the histogram (e.g. 5% of the highest gradient values) as edge pixels (edgels) and then to use the percentage to find a threshold for the gradient magnitudes. can you please tell me how to solve this?

 采纳的回答

Is your sobel image the true sobel edge filtered image, or is it the thresholded, skeletonized image returned by edge()? If it's the latter, well, that has only two values. Is sobelImage uint8 or double? You can use cumsum() to find the top 5% of the pixels
cdf = cumsum(pixelCounts) / sum(pixelCounts);
index95 = find(cdf>= 0.95, 1, 'first');
gl95 = channels(index95);

5 个评论

thank you, i am trying this. my sobel image is true sobel edge filtered image. the code for sobel image is this
grayImage= rgb2gray(rgbImage);
size(grayImage);
C=double(grayImage);
maskX = [-1 0 1 ; -2 0 2; -1 0 1];
maskY = [-1 -2 -1 ; 0 0 0 ; 1 2 1] ;
resX = conv2(C, maskX, 'same');
resY = conv2(C, maskY, 'same');
sobelImage = sqrt(resX.^2 + resY.^2);
direction = atan(resY/resX);
thresh = sobelImage < 10;
sobelImage(thresh) = 0;
imshow(sobelImage,[]);
drawnow();
i have applied it. it is showing again the white space with the scale but no histogram. the code is
[rows1, columns1, numberOfColorBands1] = size(sobelImage);
[pixelCounts, channels] = imhist(sobelImage, 256);
bar(channels, pixelCounts);
xlim([0 255]);
cdf = cumsum(pixelCounts) / sum(pixelCounts);
index95 = find(cdf>= 0.95, 1, 'first');
gl95 = channels(index95);
drawnow();
OK, my code should work. However, your code has this bad line:
direction = atan(resY/resX);
where you're doing a matrix division instead of an element by element division:
direction = atan(resY./resX);
Alright, time for a full demo:
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
imtool close all; % Close all imtool figures if you have the Image Processing Toolbox.
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;
% Check that user has the Image Processing Toolbox installed.
hasIPT = license('test', 'image_toolbox');
if ~hasIPT
% User does not have the toolbox installed.
message = sprintf('Sorry, but you do not seem to have the Image Processing Toolbox.\nDo you want to try to continue anyway?');
reply = questdlg(message, 'Toolbox missing', 'Yes', 'No', 'Yes');
if strcmpi(reply, 'No')
% User said No, so exit.
return;
end
end
% Read in a standard MATLAB gray scale demo image.
folder = fullfile(matlabroot, '\toolbox\images\imdemos');
button = menu('Use which demo image?', 'CameraMan', 'Moon', 'Eight', 'Coins', 'Pout');
if button == 1
baseFileName = 'cameraman.tif';
elseif button == 2
baseFileName = 'moon.tif';
elseif button == 3
baseFileName = 'eight.tif';
elseif button == 4
baseFileName = 'coins.png';
else
baseFileName = 'pout.tif';
end
% Read in a standard MATLAB gray scale demo image.
folder = fullfile(matlabroot, '\toolbox\images\imdemos');
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% File doesn't exist -- didn't find it there. Check the search path for it.
fullFileName = baseFileName; % No path this time.
if ~exist(fullFileName, '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
grayImage = imread(fullFileName);
% Get the dimensions of the image.
% numberOfColorBands should be = 1.
[rows columns numberOfColorBands] = size(grayImage);
% Display the original gray scale image.
subplot(2, 2, 1);
imshow(grayImage, []);
title('Original Grayscale Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
% Give a name to the title bar.
set(gcf,'name','Demo by ImageAnalyst','numbertitle','off')
maskX = [-1 0 1 ; -2 0 2; -1 0 1];
maskY = [-1 -2 -1 ; 0 0 0 ; 1 2 1] ;
SobelX = conv2(double(grayImage), maskX, 'same');
SobelY = conv2(double(grayImage), maskY, 'same');
sobelImage = sqrt(SobelX.^2 + SobelY.^2);
% Display the image.
subplot(2, 2, 2);
imshow(sobelImage, []);
title('Sobel-Filtered Image', 'FontSize', fontSize);
% direction = atan(SobelY./SobelX);
% Threshold the image to find edges less than 10,
% in other words, the smooth areas.
binaryImage = sobelImage < 10;
% Display the image.
subplot(2, 2, 3);
imshow(binaryImage, []);
title('Thresholded Image (White = Smooth areas)', 'FontSize', fontSize);
sobelImage(binaryImage) = 0;
% Display the image.
subplot(2, 2, 4);
imshow(sobelImage, []);
title('Masked (smooth areas zeroed out)', 'FontSize', fontSize);
hello sir, i have edited the code. now the sobel image code is
grayImage= rgb2gray(rgbImage);
size(grayImage);
C=double(grayImage);
maskX = [-1 0 1 ; -2 0 2; -1 0 1];
maskY = [-1 -2 -1 ; 0 0 0 ; 1 2 1] ;
resX = conv2(C, maskX, 'same');
resY = conv2(C, maskY, 'same');
sobelImage = sqrt(resX.^2 + resY.^2);
direction = atan(resY./resX);
thresh = sobelImage < 10;
sobelImage(thresh) = 0;
imshow(sobelImage,[]);
drawnow();
but it is showing the same blank image with scale.

请先登录,再进行评论。

更多回答(2 个)

hello sir, i have edited the code. now the sobel image code is
grayImage= rgb2gray(rgbImage);
size(grayImage);
C=double(grayImage);
maskX = [-1 0 1 ; -2 0 2; -1 0 1];
maskY = [-1 -2 -1 ; 0 0 0 ; 1 2 1] ;
resX = conv2(C, maskX, 'same');
resY = conv2(C, maskY, 'same');
sobelImage = sqrt(resX.^2 + resY.^2);
direction = atan(resY./resX);
thresh = sobelImage < 10;
sobelImage(thresh) = 0;
imshow(sobelImage,[]);
drawnow();
but it is showing the same blank image with scale.

17 个评论

You should have made this a comment, since it's not an answer to your original question. See my demo in my answer above.
i have re edited the code. i am giving the whole code for sobel image and histogram of sobel image .
%....part (1)[generating the histogram of the image]
baseFileName = 'violet.bmp';
fullFileName = fullfile(pwd, baseFileName);
if exist(fullFileName,'file')
rgbImage = imread(fullFileName);
[rows, columns, numberOfColorBands] = size(rgbImage);
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
grayImage= rgb2gray(rgbImage);
[pixelCounts, grayLevels] = imhist(grayImage, 256);
bar(grayLevels, pixelCounts);
xlim([0 255]);
uiwait(msgbox('Click OK to see the grayscale image'));
imshow(grayImage);
drawnow();
uiwait(msgbox('Click OK to see the baseFile RGB image'));
imshow(rgbImage);
drawnow();
else
warningMessage = sprintf('Error: file not found\n%s', fullFileName);
uiwait(warndlg(warningMessage));
end
%...end of part (1)
%........part(2) applying 1x2 and sobel operator on image and analyze the
%result of gradient magnitude image and subtracting 1x2 operator applied
%image from sobel operator applied image
%...part (2)the thresholded and skeletonized value of sobel operator
grayImage= rgb2gray(rgbImage);
size(grayImage);
BW = edge(grayImage,'sobel',0.006);
imshow(BW);
drawnow();
%....the sobel operator applied edge image
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
grayImage= rgb2gray(rgbImage);
size(grayImage);
C=double(grayImage);
maskX = [-1 0 1 ; -2 0 2; -1 0 1];
maskY = [-1 -2 -1 ; 0 0 0 ; 1 2 1] ;
resX = conv2(C, maskX, 'same');
resY = conv2(C, maskY, 'same');
sobelImage = sqrt(resX.^2 + resY.^2);
direction = atan(resY./resX);
thresh = sobelImage < 10;
sobelImage(thresh) = 0;
imshow(sobelImage,[]);
drawnow();
binaryImage = sobelImage < 10;
imshow(binaryImage, []);
drawnow();
%...part(2)1x2 operator applied edge image
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
grayImage = rgb2gray(rgbImage);
size(grayImage);
C = double(grayImage);
mX = [-1 1 0;-1 1 0;0 0 0];
mY = [1 1 0;-1 -1 0;0 0 0];
rX = conv2(C,mX,'same');
rY = conv2(C,mY,'same');
filteredImage = sqrt(rX.^2 + rY.^2);
direction1 = atan(rY./rX);
thresh = filteredImage < 10;
filteredImage(thresh) = 0;
imshow(filteredImage,[]);
cla
drawnow();
%sobel operator applied image have clear visual advantage over 1x2 operator in
%this case. sobel operated image is brighter than 1x2 edge image
%.......part(2)resulting image of 1x2 operator applied image subtracted from sobel applied
%image
clc
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
subtractedImage = imsubtract(sobelImage,filteredImage);
if (numel(filteredImage)) == 1 && isa(class(filteredImage),'double');
subtractedImage1 = imlincomb(1.0, sobelImage, -filteredImage);
else
subtractedImage1 = imlincomb(1.0, sobelImage, -1.0, filteredImage);
end
imshow(subtractedImage1,[]);
drawnow();
%yes, there are residue when we subtract 1x2 edge image from sobel edge
%image.
%......end of part (2)
%......part (3)[generating edge maps of the gradient maps]
%...edge map of the sobelImage
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
size(sobelImage);
C=double(sobelImage);
maskX = [-1 0 1 ; -2 0 2; -1 0 1];
maskY = [-1 -2 -1 ; 0 0 0 ; 1 2 1] ;
resX = conv2(C, maskX, 'same');
resY = conv2(C, maskY, 'same');
edgeMapSobel = sqrt(resX.^2 + resY.^2);
directionedgeSobel = atan(resY./resX);
threshsobel = edgeMapSobel < 10;
edgeMapSobel(threshsobel) = 0;
imshow(edgeMapSobel,[]);
drawnow();
%...edge map of the filteredImage
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
size(filteredImage);
C=double(filteredImage);
maskX = [-1 0 1 ; -2 0 2; -1 0 1];
maskY = [-1 -2 -1 ; 0 0 0 ; 1 2 1] ;
resX = conv2(C, maskX, 'same');
resY = conv2(C, maskY, 'same');
edgeMapFilter = sqrt(resX.^2 + resY.^2);
directionfilter = atan(resY./resX);
threshfilter = edgeMapFilter < 10;
edgeMapFilter(threshfilter) = 0;
imshow(edgeMapFilter,[]);
drawnow();
% generating histogram for sobelgradient edge image
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
[rows1, columns1, numberOfColorBands1] = size(sobelImage);
[pixelCounts, channels] = imhist(sobelImage, 256);
bar(channels, pixelCounts);
xlim([0 255]);
cdf = cumsum(pixelCounts) / sum(pixelCounts);
index95 = find(cdf>= 0.95, 1, 'first');
gl95 = channels(index95);
drawnow();
it is still showing the a blank histogram.
If you're going to want me to run custom code that does not use a standard demo image, then you should upload your violet.bmp image and let me know where it is.
sorry for putting this in answer.. i was supposed to put it in comment. due to some server disturbance, it is put in answer section. this is not an answer of question.
Change these lines to this:
[pixelCounts, channels] = hist(sobelImage(:), 50); % hist, not imhist
bar(channels, pixelCounts);
% xlim([0 255]); % Comment out.
i cannot upload the violet.bmp from my computer to matlab answer. is there any way to upload it?
thank you. for sobel image i can generate the histogram. but when i wish to do the same for 1x2 operator edge image then i can see again the blank screen with scale.. this is the code for sobel histogram and 1x2 histogram
[rows1, columns1, numberOfColorBands1] = size(sobelImage);
[pixelCounts, channels] = hist(sobelImage(:), 50);
bar(channels, pixelCounts);
xlim([0 255]);
cdf = cumsum(pixelCounts) / sum(pixelCounts);
index95 = find(cdf>= 0.95, 1, 'first');
gl95 = channels(index95);
subplot(2,2,1);
drawnow();
% generating histogram for 1x2 gradient edge image
[rows2, columns2, numberOfColorBands2] = size(filteredImage);
[pixelCounts, channels] = hist(filteredImage(:), 50);
bar(channels, pixelCounts);
xlim([0 255]);
cdf1 = cumsum(pixelCounts) / sum(pixelCounts);
index95a = find(cdf1>= 0.95, 1, 'first');
gl95a = channels(index95);
subplot(2,2,2);
drawnow();
You didn't change the code like I said. See where I commented out xlim()? Plus, your last subplot is not going to apply to anything since nothing comes after it.
please let me know how to overcome this issue so that i can display both the histograms. i have changed the code
% generating histogram for sobelgradient edge image
[rows1, columns1, numberOfColorBands1] = size(sobelImage);
[pixelCounts, channels] = hist(sobelImage(:), 50);
bar(channels, pixelCounts);
% xlim([0 255]); % Comment out.
cdf = cumsum(pixelCounts) / sum(pixelCounts);
index95 = find(cdf>= 0.95, 1, 'first');
gl95 = channels(index95);
subplot(2,2,1);
drawnow();
% generating histogram for 1x2 gradient edge image
[rows2, columns2, numberOfColorBands2] = size(filteredImage);
[pixelCounts, channels] = hist(filteredImage(:), 50);
bar(channels, pixelCounts);
% xlim([0 255]); % Comment out.
cdf1 = cumsum(pixelCounts) / sum(pixelCounts);
index95a = find(cdf1>= 0.95, 1, 'first');
gl95a = channels(index95a);
subplot(2,2,2);
drawnow();
i can display the histogram but i have a slight problem. after this histogram, i am trying to generate another image. i am willing to display the image in a separate window. but after the second subplot(), i can see all my next images in that second frame. this is the code.
% generating histogram for 1x2 gradient edge image
[rows2, columns2, numberOfColorBands2] = size(filteredImage);
[pixelCounts, channels] = hist(filteredImage(:), 50);
subplot(2,2,2);
bar(channels, pixelCounts);
% xlim([0 255]); % Comment out.
cdf1 = cumsum(pixelCounts) / sum(pixelCounts);
index95a = find(cdf1>= 0.95, 1, 'first');
gl95a = channels(index95a);
drawnow();
clear;
%.....part (5)..[generating each of RGB color planes]
clear
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
baseFileName = 'violet.bmp';
RGBoriginal = imread(baseFileName);
redimage=RGBoriginal(:,:,1);
greenimage=RGBoriginal(:,:,2);
blueimage=RGBoriginal(:,:,3);
imshow(redimage);
drawnow();
imshow(greenimage);
drawnow();
imshow(blueimage);
drawnow();
i can see redimage, greenimage and blueimage in second subplot frame. please let me know how to overcome this problem.
Well what frame do you want them in? In a 2 by 2 array, you can put them into 1-4.
subplot(2,2,1); % Third arg can be 1 - 4. 1-2 is first row, 3-4 is second row.
If you want more, do a 2 by 3 array and you can have up to 6 simultaneously:
subplot(2,3,1); % Third arg can be 1 - 6. 1-3 is first row, 4-6 is second row.
i am trying this but i want to put them in a complete different window

请先登录,再进行评论。

hellow sir i run your code it works fine, but i need to change this code into Prewitt's and Roberts Operators, how i can change this code? thanks

1 个评论

Yahye, simply use imgradient() - those methods are options for this function built-in to the Image Processing Toolbox.

请先登录,再进行评论。

类别

帮助中心File Exchange 中查找有关 Logical 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by