how do I threshold pixels in an image and convert the background pixels to nothing instead of zero?

I want to create a threshold for the pixels then set them to nothing.
here is what I have thus far:
%set a pixel threshold cutoff (60 is my threshold) - minimize background by choosing a
%value cutoff, such that every pixel less than that value is considered one class,
%while every pixel greater than that value is considered the other class.
I = imread('.tiff');
level = graythresh(I)
BW = imbinarize(I,level);
Display the original image next to the binary image.
imshowpair(I,BW,'montage')
end
Can this work for a RGB image?
Now I want to convert everything not of interest i.e. the background and pixels not of interest to NAN
%convert the intensity values of the background to "nothing"
% rather than to 0 and keeps the other values
After reading my image I, If i want to make all the black pixels [0 60] to NaN:
I(I>=0 & I<= 60) = NaN
Thank you so much, I am stuck at this stage and cannot move. Please help.

 Respuesta aceptada

What you gave will work for a color image and an image of any dimensions. However, there is no need to do what you asked. It's possible to do anything you want with just the regular binary image.

12 comentarios

Just to be sure I have explained my reason well:
I want to minimarize the background of a black and nonblack image. This is because I want to emphasize the nonblack pixels (make the nonblack pixel regions sharper).
For the pixels that are not in the enhanced region (i.e. the pixels that have not passed the threshold) I want them to be set to nan.
I believe this is necessary to acquire the region of interest in my image but can you suggest another way to acquire the region of interest? @Image Analyst
Thank you so much for your wisdom.
If you want the mean of pixels in the roi, you'd simply do
meanOfPixelsInRoi = mean(grayImage(roi));
For example if your roi was defined to be pixels less than 100:
grayImage = randi(255, 6, 6, 'uint8') % Create sample image.
grayImage = 6×6
98 182 52 43 46 169 176 160 180 253 56 86 201 96 19 238 12 172 154 214 241 143 202 198 179 209 128 221 130 106 134 34 40 13 53 152
roi = grayImage < 60 % Define roi by thresholding
roi = 6×6 logical array
0 0 1 1 1 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0
meanOfPixelsInRoi = mean(grayImage(roi)) % Get mean of pixels in roi
meanOfPixelsInRoi = 36.8000
I think this answers my question.
My image would have multiple blobs of pixels that are considered the ROI, spreadout across the image.
The region of interest is defined as the parts of the image that met a previouslt set criteria, how does matlab identify the region of interest?
Previously i identified the ROI by:
applying a median filter (pixel radius 2)
adjust threshold (to some value usually 60)
divide the image by itself.
MATLAB identifies the region of interest using the algorithm you tell it. Maybe it's thresholding immediately. Maybe there are some preprocessing steps until you get to the point where you have an image that you can threshold. Perhaps if you uploaded your image I could give some advice on a good algorithm for segmenting your image (finding the roi).
@Image Analyst The segmentation I have been doing to find the ROI has been repeated but I would benefit from your feedback. To find the roi, first I:
Apply a median filter which replaces each pixel with the averag of its 3x3 neighbors with a pixel radis of 2
Apply a threshold (usually 60)
Set the other pixels to NAN
divide the resulting image by itself => ROI
Here is the code that I have for that so far:
% Loads the image
I = imread('test1.jpg');
I = double(I);
%replace each pixel with the average of its 3x3 neighbors with
%filtering with a radius of 2 pixels
mean3=conv2(I,[0 1 0; 1 1 1; 0 1 0]/4,'same');
imshow(mean3, []);
%set a pixel threshold cutoff in imagej it was 60 - minimize background by choosing a
%value cutoff, such that every pixel less than that value is considered one class,
%while every pixel greater than that value is considered the other class.
roi = grayImage < 60 % Define roi by thresholding
%convert the intensity values of the background to "nothing"
%rather than to 0 and keeps the other values
VALUE(VALUE == 1) = NaN;
VALUE(VALUE == 0) = 1;
%divide this image by itself -> ROI
RegOI = double() ./ double();
imshow(RegOI, []);
meanOfPixelsInRoi = mean(grayImage(roi));
here is my error:
Error using conv2
N-D arrays are not supported.
Error in code (line 8)
mean3=conv2(I,[0 1 0; 1 1 1; 0 1 0]/4,'same');
@Neo the (badly-named) I is a color image. You can only use conv2 on a gray scale image. Convert it to gray scale.
rgbImage = imread('test1.jpg');
if size(rgbImage, 3) == 3
% Use all three color channels to convert the true color image to gray scale.
grayImage = double(rgbImage);
% Or alternatively take green channel only.
%grayImage = double(rgbImage(:, :, 2));
end
My apologizes for that @Image Analyst it was a test name.
I am a little confused by your suggestion but here is what I have after your correction.
% Loads thesingle channel image
rgbImage = imread('test1.jpg');
grayImage = double(rgbImage(:, :, 2));
%replace each pixel with the average of its 3x3 neighbors with
%filtering with a radius of 2 pixels
mean3=conv2(I,[0 1 0; 1 1 1; 0 1 0]/4,'same');
imshow(mean3, []);
%set a pixel threshold cutoff in imagej it was 60 - minimize background by choosing a
%value cutoff, such that every pixel less than that value is considered one class,
%while every pixel greater than that value is considered the other class.
roi = grayImage < 60; % Define roi by thresholding
%convert the intensity values of the background to "nothing"
%rather than to 0 and keeps the other values
VALUE(VALUE == 1) = NaN;
VALUE(VALUE == 0) = 1;
%divide this image by itself -> ROI
RegOI = double() ./ double();
imshow(RegOI, []);
but i get the same error:
Error using conv2
N-D arrays are not supported.
Error in benzaanalysis (line 15)
mean3=conv2(I,[0 1 0; 1 1 1; 0 1 0]/4,'same');
And why are you still using I in conv2() instead of grayImage? And why are you dividing by 4 when there are 5 pixels in your kernel window. Should be
mean3 = conv2(grayImage, [0 1 0; 1 1 1; 0 1 0] / 5, 'same');
Neo
Neo el 28 de Jul. de 2022
Editada: Neo el 29 de Jul. de 2022
thank you @Image Analyst but I am unsure if I want the binary image (resulting image attached) when the end goal would be to take the mean of the pixels of the blobs in the image that I shared (per ex.). Won't information about the mean of the blobs of pixels be lost without the color of the pixels? When i got the ROI (in another system processor) the background was black but the pixels of interest had color.
Side question: how can you tell there are 5 pixels in the kernel window? And does the convultion apply the 2 pixel radius?
by the way, in how the algorithm is set up are the nans being used correctly and won't spit out nonsense?
% Loads the single channel image
rgbImage = imread('test1.jpg');
grayImage = double(rgbImage(:, :, 2));
%replace each pixel with the average of its 3x3 neighbors with
%filtering with a radius of 2 pixels
mean3=conv2(grayImage,[0 1 0; 1 1 1; 0 1 0]/5,'same');
imshow(mean3, []);
%set a pixel threshold cutoff in imagej it was 60 - minimize background by choosing a
%value cutoff, such that every pixel less than that value is considered one class,
%while every pixel greater than that value is considered the other class.
roi = grayImage < 60; % Define roi by thresholding
%convert the intensity values of the background to "nothing"
%rather than to 0 and keeps the other values
%divide this image by itself -> ROI
roifinal = roi./roi;
imshow(roifinal, []);
meanOfPixelsInRoi = mean(grayImage(roi));

Iniciar sesión para comentar.

Más respuestas (1)

This is my understand from your question. All value <60 will be convert to NaN
I =imread('corn.tif')
I = 415×312
105 105 39 88 27 42 38 99 61 99 75 88 39 105 69 52 52 69 105 39 39 21 85 85 85 69 52 118 118 118 35 88 50 71 42 38 99 100 86 100 42 50 88 88 39 39 39 39 39 21 21 71 85 63 85 39 69 52 31 31 71 71 71 38 99 99 100 100 110 124 100 42 27 88 88 88 88 39 88 21 71 24 99 63 14 39 69 52 52 52 42 42 38 99 99 100 100 110 86 16 100 22 38 42 71 27 71 71 71 71 38 99 63 100 99 71 39 69 69 69 99 99 99 100 100 100 100 100 86 100 44 86 22 99 42 42 42 38 85 38 63 99 100 113 25 71 39 39 69 69 38 38 99 38 38 42 99 22 99 22 100 100 86 100 100 100 99 99 100 63 100 61 61 110 113 99 81 39 39 41 42 42 42 50 50 71 42 71 42 42 99 99 100 86 86 100 44 100 100 100 86 16 110 124 124 99 17 71 41 41 71 50 50 88 88 50 88 88 71 71 71 38 99 34 86 16 22 22 104 44 61 86 86 110 110 34 99 17 71 71 50 50 78 35 35 78 88 88 27 71 71 71 99 99 34 86 22 22 22 38 95 89 100 8 61 100 99 14 17 17 88 35 19 35 35 39 88 107 50 88 71 71 42 99 100 100 22 97 75 42 24 24 42 24 38 63 100 99 99 17
VALUE = double((I<=60))
VALUE = 415×312
0 0 1 0 1 1 1 0 0 0 0 0 1 0 0 1 1 0 0 1 1 1 0 0 0 0 1 0 0 0 1 0 1 0 1 1 0 0 0 0 1 1 0 0 1 1 1 1 1 1 1 0 0 0 0 1 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 1 0 1 0 0 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 1 0 1 1 1 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 1 1 0 1 0 0 0 0 1 0 1 1 0 0 1 1 0 1 1 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 1 0 1 1 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 1 1 0 1 1 0 0 1 0 0 0 0 0 1 0 1 0 1 1 1 0 1 0 0 0 0 0 1 0 1 0 0 1 1 0 1 1 0 0 0 1 0 0 0 0 0 1 0 1 1 1 1 0 0 0 1 0 0 0 1 1 1 0 1 1 1 1 1 0 0 1 0 0 0 1 0 0 0 1 0 0 1 1 1 1 1 1 0 0 0 0 1
VALUE(VALUE == 1) = NaN;
VALUE(VALUE == 0) = 1;
double(I).*VALUE
ans = 415×312
105 105 NaN 88 NaN NaN NaN 99 61 99 75 88 NaN 105 69 NaN NaN 69 105 NaN NaN NaN 85 85 85 69 NaN 118 118 118 NaN 88 NaN 71 NaN NaN 99 100 86 100 NaN NaN 88 88 NaN NaN NaN NaN NaN NaN NaN 71 85 63 85 NaN 69 NaN NaN NaN 71 71 71 NaN 99 99 100 100 110 124 100 NaN NaN 88 88 88 88 NaN 88 NaN 71 NaN 99 63 NaN NaN 69 NaN NaN NaN NaN NaN NaN 99 99 100 100 110 86 NaN 100 NaN NaN NaN 71 NaN 71 71 71 71 NaN 99 63 100 99 71 NaN 69 69 69 99 99 99 100 100 100 100 100 86 100 NaN 86 NaN 99 NaN NaN NaN NaN 85 NaN 63 99 100 113 NaN 71 NaN NaN 69 69 NaN NaN 99 NaN NaN NaN 99 NaN 99 NaN 100 100 86 100 100 100 99 99 100 63 100 61 61 110 113 99 81 NaN NaN NaN NaN NaN NaN NaN NaN 71 NaN 71 NaN NaN 99 99 100 86 86 100 NaN 100 100 100 86 NaN 110 124 124 99 NaN 71 NaN NaN 71 NaN NaN 88 88 NaN 88 88 71 71 71 NaN 99 NaN 86 NaN NaN NaN 104 NaN 61 86 86 110 110 NaN 99 NaN 71 71 NaN NaN 78 NaN NaN 78 88 88 NaN 71 71 71 99 99 NaN 86 NaN NaN NaN NaN 95 89 100 NaN 61 100 99 NaN NaN NaN 88 NaN NaN NaN NaN NaN 88 107 NaN 88 71 71 NaN 99 100 100 NaN 97 75 NaN NaN NaN NaN NaN NaN 63 100 99 99 NaN

14 comentarios

Sorry, what does double(I).*VALUE mean?
Bear in mind that at this point, you have an improperly-scaled image full of NaNs. If you need the NaNs for a certain purpose, that's fine. If you try to feed the image to certain functions (e.g. imshow(), imwrite()), you'll get nonsense out.
If you want an image that's at least still scaled for its class:
inpict = imread('cameraman.tif');
mask = inpict<=60; % select dark pixels
outpict = im2double(inpict); % cast and scale
outpict(mask) = NaN; % use the mask itself
I should point out that corn.tif is an indexed image, so thresholding it by index alone doesn't really make any sense.
double(I).*VALUE this is normal multiple of array double just use to covert from logical to double
Again, I doubt having nans is necessary. What do you think you can't do if they remain as 0's?
I kind of agree with IA here. Unless you have a particular reason, it shouldn't be a common practice.
If you're thinking that you can use NaNs to make parts of an image appear transparent in a figure, that doesn't work. NaNs are simply rendered as opaque black, so it's visually equivalent to using zero.
A = imread('cameraman.tif');
B = imread('cman_01.png'); % color version of the above
mk = A<150; % select dark regions
A = im2double(A);
A(mk) = NaN;
imshow(B); hold on % show color image
imshow(A) % put image with NaNs on top
As you can see, this doesn't accomplish anything. If you wanted transparency, you could do it with the mask itself.
A = imread('cameraman.tif');
B = imread('cman_01.png'); % color version of the above
mk = A<150; % select dark regions
figure
imshow(B); hold on % show color image
hi = imshow(A); % put gray image on top
hi.AlphaData = ~mk; % set the alphadata
Similarly, trying to save images with transparency won't work by embedding NaNs in the image.
That said, there are some tools (e.g. John's inpaint_nans()) that can be utilized by embedding the mask into the image using NaNs.
Thank you very much all.
I am converting to nan because of habit. In another software (imagej) I would convert to nan after thresholding so that I can get the region of interest pixels ONLY.
After this conversion to nans of the piels of noninterest, I will divide the image by itself to get the region of interest. Since the nans were set to nothing the idea would be that the region of interest image would onbly be the region of interest.
Is there another way to accomplish what I have desired?
Thanks.
Yes, the region of interest is simply the binary image you get from thresholding.
roi = grayImage < someThreshold;
If you want a 1-D list of all pixel values in the ROI (usually you don't need to use this though) you can simply do
pixelsInROI = grayImage(roi);
Not sure what you really want to accomplish. Let's say that you have your ROI, by whatever method. Then what would you do with it? Some kind of blob analysis like getting the blobs' mean intensities, areas, diameters, count, etc.?
So, I would code ROI < 60; ?
What do you mean by 1-D list of the pixel values? You mean the mean, intensities, count?
I’m interested in the mean of the pixels in the ROI
As an example:
grayImage = randi(255, 5, 10)
grayImage = 5×10
22 169 69 237 53 144 244 57 218 128 201 2 69 164 78 132 5 219 18 6 143 200 188 4 212 112 236 55 2 95 200 133 246 174 71 201 30 65 112 119 152 247 137 245 121 148 227 8 136 218
% Get a 2-D ROI by thresholding.
roi = grayImage < 60
roi = 5×10 logical array
1 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 1 0 1 1 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0
% Count the number of pixels in the ROI
numPixelsInROI = nnz(roi)
numPixelsInROI = 12
% Get only the pixels in the ROI in a 1-D column vector.
pixelsInROI = grayImage(roi)
pixelsInROI = 12×1
22 2 4 53 5 30 57 55 8 18
% Get the mean of those pixels.
meanOfPixelsInROI = mean(pixelsInROI)
meanOfPixelsInROI = 21.8333
Do you have a visual representation of the numpixelsinroi = 12 function? @Image Analyst
Neo
Neo el 29 de Jul. de 2022
Editada: Neo el 29 de Jul. de 2022
Do you have a visual representation of the pixel count? or the image that you used? Or is this the image I gave?
No. I don't have a visual representation of the number of pixels - that's just a number. How would you visualize 12?
The data are from the small random image I created. Apply to your image by adapting the demo code.

Iniciar sesión para comentar.

Preguntada:

Neo
el 21 de Jul. de 2022

Editada:

Neo
el 29 de Jul. de 2022

Community Treasure Hunt

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

Start Hunting!

Translated by