1

I have a black/white image I0 (512 x 512) to which I have to remove the first k pixel and calculate the histogram of the resulting image.

Let me explain: I have to build the histogram of the image I0 without considering the first k pixels.

This is my code:

k = 8;

% compute the histogram of the entire image I0
[vecComp, histComp] = histKtoEnd(I0, 0, k);

% compute the histogram of the image I0 without the first k pixel    
[vecWithoutKPixel, histWithoutKPixel] = histKtoEnd(I0, k, k); 

where:

function [vecWithoutKPixel, hist] = histKtoEnd(image, k, colorDepth)
    % image to row vector
    imageVec = reshape(image.', [], 1);
    l = length(imageVec); 

    % I "delete" the first k pixel
    vecWithoutKPixel = imageVec((k+1) : l-1);
    vecWithoutKPixel(end+1) = imageVec(l); 

    % inizialization
    hist = zeros(1, 2^colorDepth); 

    % create the vector of occurrences
    for i = 0 : (2^colorDepth - 1) 
        grayI = (vecWithoutKPixel == i);
        hist(1, i+1) = sum(grayI(:));
    end
end

To display the two histograms do:

subplot(1, 2, 1);
bar(0:2^k-1, histComp, 'r'); 
title('Histogram of the entire image'); 
axis([minColor, maxColor, 0, numberOfPixels]);
subplot(1, 2, 2);
bar(0:2^k-1, histWithoutKPixel, 'r'); 
title('Histogram of the image without the first k pixels'); 
axis([minColor, maxColor, 0, numberOfPixels]);

and I get: enter image description here

As you can see, the histograms are very different, yet should differ very little since the difference is only 8 pixels.

Where am I wrong?

Also in warkspace the newly created variables have these dimensions:

vecComp -> 262144 x 1 uint8
histComp -> 1 x 256 double
vecWithoutKPixel -> 65528 x 1 uint8
histWithoutKPixel -> 1 x 256 double

This is very strange. I should have:

vecComp -> 262144 x 1
vecWithoutKPixel -> 262136 x 1

Could someone help me? Thank you


I'm working with DICOM images and the command info = dicominfo(filename) get

size = info.FileSize; % 262582; 
colorType = info.ColorType; % grayscale

So I don't think that the problem is the image.

If I put a brakpoint on line vecWithoutKPixel(end+1) = imageVec(l); I get that imageVec is 262144 x 1 uint8, and:

function [vecWithoutKPixel, hist] = histKtoEnd(image, k, colorDepth)
    % image to row vector
    imageVec = reshape(image.', [], 1);
    l = length(imageVec); 

    size(imageVec) % 262144 x 1

    % I "delete" the first k pixel
    vecWithoutKPixel = imageVec((k+1) : l-1);
    vecWithoutKPixel(end+1) = imageVec(l); 

    % inizialization
    hist = zeros(1, 2^colorDepth); 

    % create the vector of occurrences
    for i = 0 : (2^colorDepth - 1) 
        grayI = (vecWithoutKPixel == i);
        hist(1, i+1) = sum(grayI(:));
    end
end

If I change the commands vecWithoutKPixel = imageVec((k+1) : l-1); vecWithoutKPixel(end+1) = imageVec(l); with vecWithoutKPixel = imageVec((k+1) : l); I get that vecWithoutKPixel = [].

  • Could you put a breakpoint on the line `vecWithoutKPixel = imageVec((k+1) : l-1);` and check the dimension of `imageVec` using `size(imageVec)`? Also 1) `(k+1) : (l-1)` might be different and 2) Why did you "delete" the last element and then put it back? – Yvon Mar 04 '17 at 18:23
  • And try `imageVec = image(:);` – Yvon Mar 04 '17 at 18:25
  • Well the real problem is in your image data. I believe you are dealing with a B/W picture, but it is stored as a RGBA image in Matlab. This can be seen by the size of the original image. You have to convert it to true B/W at first. – Yvon Mar 04 '17 at 18:30
  • @Yvon Thanks for the reply! I edited my main question. –  Mar 04 '17 at 19:07
  • `vecComp` length is `262144`, and `vecWithoutKPixel` length is `65528`. Instead of removing 8 elements, you removed `262144 - 65528` elements. You mentioned `I0` is (256 x 256), so number of elements should be `256* 256` = `65536`, yet you are getting `262144`. `256*256*4` = `262144`. In case resolution is 256x256, there are 4 elements per pixel (likely RGBA format like Yoav mentioned). – Rotem Mar 04 '17 at 22:32
  • When I tried to reproduce your problem (using RGBA input), I am getting an error in `reshape(image.', [], 1);`. I suspect bug might be involved with Matlab 2016b new feature called [implicit expansion](https://nickhigham.wordpress.com/2016/09/20/implicit-expansion-matlab-r2016b/). Are you using Matlab 2016b? (I am using an older version). – Rotem Mar 04 '17 at 22:36
  • @Rotem Sorry I misspelled, in reality the picture is 512x512 (not 256x256). I'm using Matlab 2014b. –  Mar 05 '17 at 08:14
  • Your first image shows 60,000 pixels in the first bin (brightness=0 on left side of histogram) and the second one shows 25,000 pixels in the first bin so you have removed more than the 8 pixels you claim. – Mark Setchell Mar 05 '17 at 11:20
  • @valerie So how come `vecWithoutKPixel` length is only `65528` (when it should be `262136`)? – Rotem Mar 05 '17 at 12:48

2 Answers2

0

I believe the problem is that the image data is originally in uint8 format and gets converted to double at some point. Therefore, the line

grayI = (vecWithoutKPixel == i);

in histKtoEnd probably only works with the uint8 data ( since you compare the data with an integer).

Try adding the line

vecWithoutKPixel = uint8(vecWithoutKPixel);

to the histKtoEnd function:

function [vecWithoutKPixel, hist] = histKtoEnd(image, k, colorDepth)
    % image to row vector
    imageVec = reshape(image.', [], 1);
    l = length(imageVec); 

    % I "delete" the first k pixel
    vecWithoutKPixel = imageVec((k+1) : l-1);
    vecWithoutKPixel(end+1) = imageVec(l); 

    % inizialization
    hist = zeros(1, 2^colorDepth); 

    % create the vector of occurrences
    for i = 0 : (2^colorDepth - 1) 
        vecWithoutKPixel = uint8(vecWithoutKPixel);  % Cast to integer
        grayI = (vecWithoutKPixel == i);
        hist(1, i+1) = sum(grayI(:));
    end
end
Richard
  • 1,020
  • 8
  • 16
  • Thank you for the reply. I tried to apply the changes you suggested but I always have the same problem... –  Mar 05 '17 at 08:15
0

Creating a 'random-image' using I0=randi(255,100,100) and then running your code will produce a plot like this: Histogram of randomly created image I guees this plot looks exactly like it should and the dimensions of the variables are correct as well:

vecComp 10000x1 double
vecWithoutKPixel 9992x1 double

Thus our problem is not actually your code, but your image. Your image is not really gray level valued which has been mentioned by others before. But instead of casting some variables to uint8 like @Richard suggested, you should cast your image to double. If your image is rgb valued use I0=double(rgb2gray(I0)); or if it is just uint8 for some other reason use I0=double(I0) and then pass it to the function. Hope this helps.

Max
  • 1,471
  • 15
  • 37