changing values of pixels in an image pixel by pixel ( Thresholding )

217 views (last 30 days)
Hi everyone, I'm trying to put a threshold on a grayscale image, and I'm doing it this way: that a "for" loop reads the image pixel by pixel, and if the value of the pixel is less than "0.5" sets its' value to "0", and if it is more than "3", sets it to "256". Here it is my code:
my_image =imread('picture.tif');
for R=1:num of Rows
for C=1:num of Columns
pixel=my_image(R,C);
if pixel<0.50000000 , pixel=0.000000000;, end
if pixel>3.00000000 , pixel=256;, end
thresh(R,C)=pixel;
end
end
im_thresh=mat2gray(thresh);
figure,imshow(im_thresh);
title('thresholding');
But it doesn't work properly. Sometimes it misses some values that ought to be changed, and sometimes changes the ones that shouldn't be changed, to arbitrary values…for example changes the value "0.8182" to "0.0032". It also doesn't have enough accuracy, for example instead of changing the value "0.425" to "0", changes it to "0.0002". Could you please tell me what's causing this problem, and help me to fix the code?! Thanks in advance…
  4 Comments
Image Analyst
Image Analyst on 9 Nov 2016
Waleed, since Mithra asked this 3 years ago, you might want to consider asking your own new question, and attach your image.

Sign in to comment.

Accepted Answer

Geert
Geert on 5 Sep 2013
Edited: Geert on 5 Sep 2013
First of all, it is not necessary to loop over all pixels individually. You can simply use operations on your image matrix, which would look like this:
% read in tiff image and convert it to double format
my_image = im2double(imread('picture.tif'));
my_image = my_image(:,:,1);
% perform thresholding by logical indexing
image_thresholded = my_image;
image_thresholded(my_image>3) = 256;
image_thresholded(my_image<0.5) = 0;
% display result
figure()
subplot(1,2,1)
imshow(my_image,[])
title('original image')
subplot(1,2,2)
imshow(image_thresholded,[])
title('thresholded image')
The line image_thresholded(my_image>3) = 256; is an example of logical indexing, it will assign the value 256 to all matrix elements in image_thresholded for which the same matrix element in my_image is larger than 3.
If you prefer looping over all pixels (which is not advisable due to its slow speed), your code should look something like this:
% read in tiff image and convert it to double format
my_image = im2double(imread('picture.tif'));
my_image = my_image(:,:,1);
% allocate space for thresholded image
image_thresholded = zeros(size(my_image));
% loop over all rows and columns
for ii=1:size(my_image,1)
for jj=1:size(my_image,2)
% get pixel value
pixel=my_image(ii,jj);
% check pixel value and assign new value
if pixel<0.5
new_pixel=0;
elseif pixel>3
new_pixel=256;
else
new_pixel = pixel;
end
% save new pixel value in thresholded image
image_thresholded(ii,jj)=new_pixel;
end
end
% display result
figure()
subplot(1,2,1)
imshow(my_image,[])
title('original image')
subplot(1,2,2)
imshow(image_thresholded,[])
title('thresholded image')
Does this help you out?
  13 Comments
Imran Riaz
Imran Riaz on 4 Aug 2022
This is my final masked image but the task is to remove the black area and the output contains 95% of finger pixels only. Bcz some pixels of black area will remain there.
Image Analyst
Image Analyst on 4 Aug 2022
@Imran Riaz let's not continue to discuss here on @Mithra's thread (which sends him emails). Please start a new discussion thread and attach your original image. And say why you want it cropped and can't process it as it is (like you just want to magnify the ROI or something).
If you have any more questions, then attach your data and code to read it in with the paperclip icon after you read this:

Sign in to comment.

More Answers (2)

Laurent
Laurent on 5 Sep 2013
Hi,
First I don't understand how your original image can have non-integer pixel values, because it seems your image is 8-bit from how you access the pixel-values. Is the value '0.8182' a pixel-value in your original image? Without the image itself it will be difficult to exactly determine what is going on.
Anyway, you can remove the for-loops and do it as follows:
thresh=my_image;
thresh(thresh<0.5)=0;
thresh(thresh>3)=255;
If your image is 8-bit, the values go from 0 to 255, not to 256.
  3 Comments
Image Analyst
Image Analyst on 6 Sep 2013
OK. Floating point images (either single or double) can have a value of 256, whereas uint8 are limited to 255. But I see no reason at all why you would want that particular value. Can you explain why?

Sign in to comment.


Image Analyst
Image Analyst on 5 Sep 2013
Are you sure your tiff image has fractional values? I know it's a very flexible format and may allow floating point pixel values but it's not common. Anyway, you probably don't want a thresholded image with values of 0 and 256 and intact/unchanged values in the range 0.5 to 3.0. What are you going to do with the result anyway? Once I know that I can tell you how to proceed. You may want a binary image (the usual result of thresholding) to do what you need to do rather than another floating point image.
  2 Comments
Mithra
Mithra on 6 Sep 2013
I'm doing some morphological operations on this image, and in this point it's a double image. I want all pixel values less than 0.5 to be set on 0, and all pixel values more than 3 to be set as the highest value that a double image can have... which I assume is:
realmax('double')
ans =
1.7977e+308
the number 256 set by me previously was just an example indeed.
Image Analyst
Image Analyst on 6 Sep 2013
But why? Are you familiar with morphology? Do you know how grayscale morphology differs from binary morphology (my guess is no)? OK, let me ask...after you do this grayscale morphology that you plan on doing, what do you want the result to be? Please upload an image and tell me what you want to find/measure/enhance in it.

Sign in to comment.

Categories

Find more on Image Processing Toolbox in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!