I have a proplem when dealing with images in matlab, i have a white image and when i try to print the gray level of the image and increment it by 1 , it gives me 255, it never give me 256.
and here is the code. and the count is 0.
function [ count ] = white( I )
[row,col]=size(I);
count=0;
for x=1:row
for y=1:col
g=I(x,y); %the value of the gray level on each pixel
if((g+1) == 256)
count=count+1;
256
end
end
end
Your image class is probably uint8 and 255 is the maximal value of this class . For example:
>> uint8(inf)
ans =
255
Instead try to cast to a different class, for example I=uint32(I) ...
Following #Aganders3, I'll also offer a solution to your code that doesn't use for loops:
count=sum(I(:)>threshold); % Credit to #Jonas and #Aganders3
where threshold is the gray level you want to threshold
I think nate is correct on why this is not working.
Also, consider a much simpler solution to your problem (given I is full of integers):
count = sum(vector(I == intmax(class(I))));
Related
I have already uploaded the image. I need to answer below questions.
a. Load the “cameraman” image. Convert it to a double array. Determine maximum (Imax) and the minimum (Imin) pixel value of the image
b. Write a code to rescale the image such that all pixels with value< 1.25*Imin are equated to 1.25*Imin and all pixels with value > 0.75*Imax are equated to the 0.75*Imax.
c. Display the new image.
I have tried below codes but all I get is a black image.
**A = imread('D:\Matlab files\BRAIN 180\IMG-0002-00067.bmp','bmp')
I = rgb2gray(A);
I2 = double(I)/255;
%subplot(2,2,1)
%imshow(I2)
Imin=min(I2(:))
Imin
Imax=max(I2(:))
Imin
for i=1:256
for j=1:256
if I2(i,j)<1.25;
I2(i,j)=1.25*Imin;
else
I2(i,j)=0.75*Imax;
end
end
end
imshow(I2)**
Your question asks for "value< 1.25*Imin" but in your code you wrote I2(i,j)<1.25, the Imin is missing.
Second problem, the condition "value > 0.75*Imax" is required by the question but not found in your code.
I am pretty new to Matlab and encountered a problem when working with images.
I want to get a pixel that is in a specific colour (blue) in the following image:
image
My current code looks something like this:
function p = mark(image)
%// display image I in figure
imshow(image);
%// first detect all blue values higher 60
high_blue = find(image(:,:,3)>60);
%cross elements is needed as an array later on, have to initialize it with 0
cross_elements = 0;
%// in this iteration the marked values are reduced to the ones
%where the statement R+G < B+70 applies
for i = 1:length(high_blue)
%// my image has the size 1024*768, so to access the red/green/blue values
%// i have to call the i-th, i+1024*768-th or i+1024*768*2-th position of the "array"
if ((image(high_blue(i))+image(high_blue(i)+768*1024))<...
image(high_blue(i)+2*768*1024)+70)
%add it to the array
cross_elements(end+1) = high_blue(i);
end
end
%// delete the zero element, it was only needed as a filler
cross_elements = cross_elements(cross_elements~=0);
high_vector = zeros(length(cross_elements),2);
for i = 1:length(cross_elements)
high_vector(i,1) = ceil(cross_elements(i)/768);
high_vector(i,2) = mod(cross_elements(i), 768);
end
black = zeros(768 ,1024);
for i = 1:length(high_vector)
black(high_vector(i,2), high_vector(i,1)) = 1;
end
cc = bwconncomp(black);
a = regionprops(cc, 'Centroid');
p = cat(1, a.Centroid);
%// considering the detection of the crosses:
%// RGB with B>100, R+G < 100 for B<150
%// consider detection in HSV?
%// close the figure
%// find(I(:,:,3)>150)
close;
end
but it is not optimized for Matlab, obviously.
So i was wondering if there was a way to search for pixels with specific values,
where the blue value is larger than 60 (not hard with the find command,
but at the same time the values in the red and green area not too high.
Is there a command I am missing?
Since English isn't my native language, it might even help if you gave me some suitable keywords for googling ;)
Thanks in advance
Based on your question at the end of the code, you could get what you want in a single line:
NewImage = OldImage(:,:,1) < SomeValue & OldImage(:,:,2) < SomeValue & OldImage(:,:,3) > 60;
imshow(NewImage);
for example, where as you see you provide a restriction for each channel using logical operators, that you can customize of course (eg. using | as logical OR). Is this what you are looking for? According to your code you seem to be looking for specific regions in the image like crosses or coins is that the case? Please provide more details if the code I gave you is completely off the track :)
Simple example:
A = imread('peppers.png');
B = A(:,:,3)>60 & A(:,:,2)<150 & A(:,:,1) < 100;
figure;
subplot(1,2,1);
imshow(A);
subplot(1,2,2)
imshow(B);
Giving this:
I have an image of size 640X480. I want to segment it into 40X40 and then apply a common operation on each segment. so I did something like this:
A= imread('image.jpg');
for a=0:11;
for b= 0:15;
B=A((1+a*40):(a+1)*40,(1+b*40):(b+1)*40);
....... the common program for each segment........
C= result; %result of the operation
end
end
My question is how can I label C differently for each segment so that I can use these further for adding these segments back or else.
I tried defining B something like this:
A= imread('image.jpg');
for a=0:11;
for b= 0:15;
B=A((1+a*40):(a+1)*40,(1+b*40):(b+1)*40);
....... the common program for each segment........
C((a+1),(b+1))= result %result of the operation
end
end
Had it worked, I could have used C(i,j) as variable(name) but it ended as an error. What else I can do for labeling the results of the for loop.
I hope my question is understandable.
Use cell array for C
C{ a+1, b+1 } = result;
You many also want to check blockproc
If your result is always 40x40, I would use a 4d result matrix:
%preallocate at the beginning
C=nan(11,15,40,40)
And to fill within the loop
C(a+1,b+1,:,:)=result
So I have a certain grayscale image as a binary file. After I red in the image, I tried to create a series of "if" loops in order to replace a range of values with one value, and leave the rest of the matrix untouched.
I used this code
if myimage < 20
myimage = 0;
else if 20 < myimage <40
myimage = 20;
else if 40 < myimage < 60
myimage = 40;
else if 60<myimage<80
myimage = 60;
end
end
end
end
but for some reason it failed to load an image. After some debugging I figured out that the file was becoming a 1 x 1 matrix with the value "20" after the "else if 20...." line. Can anyone help me figure out why exactly this is happening? thanks.
You need to change the specific indices in myimage that have a specific value. The way your currently calling it, you're overwriting the myimage variable with a specific value. One way to find all the relevant indices is with find:
find(myimage==20)
in order to find and replace all the values with a one liner, reference the indices of interest in myimage:
myimage(find(myimage<20))=0;
and to combine multiple sets of indices (eg values >20 AND <40), use intersect:
myimage(intersect(find(myimage>20),find(myimage<40)))=20;
I am particularly stuck in this case
I = imread('liftingbody.png');
S = qtdecomp(I,.27);
blocks = repmat(uint8(0),size(S));
for dim = [512 256 128 64 32 16 8 4 2 1];
numblocks = length(find(S==dim));
if (numblocks > 0)
values = repmat(uint8(1),[dim dim numblocks]);
values(2:dim,2:dim,:) = 0;
blocks = qtsetblk(blocks,S,dim,values);
end
end
blocks(end,1:end) = 1;
blocks(1:end,end) = 1;
imshow(I), figure, imshow(blocks,[])
( The example above is from the MATLAB help )
If I try to write the image i.e blocks using imwrite(blocks) then the whole image appears to be black. This happens for any input images. But I want to write exactly the output that imshow shows here. Can anyone help ?
You created blocks as a uint8 matrix. By convention, MATLAB and Image Processing Toolbox treat a uint8 grayscale as having a range of values from 0 to 255. That is, 0 is black and 255 is white. So your blocks matrix, which contains only 0s and 1s, would normally be displayed as black and almost-black.
When you displayed blocks using:
imshow(blocks,[])
You used the "auto-ranging" syntax of imshow, which displays the minimum value of blocks as black and the maximum value of blocks as white.
But then when you saved blocks using imwrite, it made the normal assumption of 0 as black and 255 as white.
Try initializing blocks as a logical matrix instead, like this:
blocks = logical(size(S));
MATLAB and Image Processing Toolbox treat a logical matrix as a binary image and will display 0 as black and 1 and white. If you pass a logical matrix to imwrite, it will create a 1-bit-depth binary image file.
a generic answer is to normalize the image to be in the range for imwrite(blocks):
imwrite((blocks-min(blocks))/(max(blocks)-min(blocks)))