When we read color image information
we will get data in rows x cols x 3(RGB color)
I want to extract the min value from separate color
Originally I could do
R = I(:,:,1);
G = I(:,:,2);
B = I(:,:,3);
to extract separate data color and normally find min by
Rmin = min(R(:));
and so on...
but Is there any proper solution to use min?
I tried
min(I(:,:,1:3));
but it didn't right (dimension answer was 1xcolx3 : It should be 1x3)
My guess is you have to use the nested min. For example use the following command
min(min(I, [], 1), [], 2)
This should give the result you want.
Try this:
min(min(min(I,3)))
or for a cleaner output:
squeeze(min(min(min(I,3))))
There is probably a nicer way, without nesting the min function.
Related
Lets say I have a matrix x=[ 1 2 1 2 1 2 1 2 3 4 5 ]. To look at its histogram, I can do h=hist(x).
Now, h with retrieve a matrix consisting only the number of occurrences and does not store the original value to which it occurred.
What I want is something like a function which takes a value from x and returns number of occurrences of it. Having said that, what one thing histeq does should we admire is, it automatically scales nearest values according!
How should solve this issue? How exactly people do it?
My reason of interest is in images:
Lets say I have an image. I want to find all number of occurrences of a chrominance value of image.
I'm not really shure what you are looking for, but if you ant to use hist to count the number of occurences, use:
[h,c]=hist(x,sort(unique(x)))
Otherwise hist uses ranges defined by centers. The second output argument returns the corresponding number.
hist has a second return value that will be the bin centers xc corresponding to the counts n returned in form of the first return value: [n, xc] = hist(x). You should have a careful look at the reference which describes a large number of optional arguments that control the behavior of hist. However, hist is way too mighty for your specific problem.
To simply count the number of occurrences of a specific value, you could simply use something like sum(x(:) == 42). The colon operator will linearize your image matrix, the equals operator will yield a list of boolean values with 1 for each element of x that was 42, and thus sum will yield the total number of these occurrences.
An alternative to hist / histc is to use bsxfun:
n = unique(x(:)).'; %'// values contained in x. x can have any number of dims
y = sum(bsxfun(#eq, x(:), n)); %// count for each value
I have two geotiff images (saying "A" and "B") imported in Matlab as matrices with Geotiffread. One has different values, while the second has only 0 and 255s.
What I'd like to do is replacing all the 255s with the values inside the other image (or matrix), according to their positions.
A and B differs in size, but they have the same projections.
I tried this:
A (A== 255)= B;
the output is the error:
??? In an assignment A(:) = B, the number of elements in A and B must be the same.
Else, I also tried with the logical approach:
if A== 255
A= B;
end
and nothing happens.
Is there a way to replace the values of A with values of B according to a specific value and the position in the referenced space?
As darthbith put in his comment, you need to make sure that the number of entries you want to replace is the same as the number values you are putting in.
By doing A(A==255)=B you are trying to put the entire matrix B into the subset of A that equals 255.
However, if, as you said, the projections are the same, you can simply do A(A==255) = B(A==255), under the assumption that B is larger or the same size as A.
Some sample code to provide a proof of concept.
A = randi([0,10],10,10);
B = randi([0,4],15,15);
C = A % copy original A matrix for comparison later
A(A==5) = B(A==5); % replace values
C==A % compare original and new
This example code creates two matrices, A is a 10x10 and B is a 15x15 and replaces all values that equal 5 in A with the corresponding values in B. This is shown to be true by doing C==A which shows where the new matrix and the old matrix vary, proving replacement did happen.
It seems to me that you are trying to mask an image with a binary mask. You can do this:
BW = im2bw(B,0.5);
A=A.*BW;
hope it helps
Try A(A==255) = B(A==255). The error is telling you that when you try to assign values to the elements of an array, you cannot give it any more or fewer values than you are trying to assign.
Also, regarding the if statement: if A==255 means the same as if all(A==255), as in, if any elements of A are not 255, false is returned. You can check this at the command line.
If you're really desperate, you can use a pair of nested for loops to achieve this (assuming A and B are the same size and shape):
[a,b] = size(A);
for ii = 1:a
for jj = 1:b
if A(ii,jj) == 255
A(ii,jj) = B(ii,jj);
end
end
end
I'm working on a color image segmentation in HSV color space using Matlab fuzzy toolbox.
the goal is to read an RGB image->convert to hsv->use H,S,V values as an input for fuzzy system and then find which class(here is our 16 constant output color) does this pixel belongs.
here is the fuzzy system :
"The reasoning procedure is based on a zero-order Takagi-Sugeno model, so that the consequent part of each fuzzy rule is a crisp discrete value of the set{Black, White, Red, Orange,etc}.
Since this model has 10 fuzzy sets for Hue, 5 for Saturation and 4 for Value, the total number of rules required for this model is 10*5*4=200".(1)
The problem is that when I use this line in my program to get output value
segimg=reshape(evalfis([h s v],hsvRuleSugeno),imgh,imgw);
the out put is not any of my constant classes, because it uses centroid for defuzzification and as you see below I can't rely on it, as an output !
I search many papers and websites but I think it's so simple that no one explained it! I'm missing something or probably i don't have enough knowledge would you please help me to understand this problem ?
reference:
(1): Human Perception-based Color Segmentation Using Fuzzy Logic,Lior Shamir Department of Computer Science, Michigan Tech.
The paper explains the computation process in section 2.3. You do not need non-discrete or centroid value as obtained from evalfis. I'm assuming you have made all the rules which must be giving one of the 16 classes as output. That means each each output class is associated with at least one rule. According to the paper, you need to:
Make 16 groups containing rules associated to each output class. One group for yellow, one for white and one for black so on...
Calculate the strength of each and every rule.
For each group, find summation of strength value of all the rules contained in that group.
Then find the group with maximum cumulative sum of strength of its contained rules.
To achieve this, we cannot rely on centroid based defuzzified value. I checked the documentation on evalfis and below is script that should be able to perform above algorithm. Idea is to collect strength of each rule, order the rules into groups based on rule's output class, then find summation of each group and find maximum.
[output, IRR, ORR, ARR] = evalfis(input, fismat)
m = cat(2, ORR, ARR);
m = sortrows(m, 1)
r = [];
for l = 2 : size(m, 1)
if m(l, 1) ~= m(l - 1, 1)
r = cat(1, r, m(l - 1, :));
else
m(l, 2) = m(l, 2) + m(l - 1, 2);
end
end
if size(m, 1) >= 2
r = cat(1, r, m(size(m, 1), :));
end
% r now contains the final class to be choosen
disp(r)
Thanks a lot for your answer Shivam,
Actually your code has an error but I got the idea and started working on it, and finally found what to do ! here is what I use and the result was OK ! now I have to work on adjusting rules to get better results
for i=1:imh
for j=1:imw
[output, IRR, ORR, ARR] = evalfis([h(i,j);s(i,j);v(i,j)], hsvRuleSugeno);
m = cat(2,ARR,ORR);
[trash,idx] = unique(m(:,1),'first');
out = m(sort(idx),:);
out(:,[1,2])=out(:,[2,1]);
out = sortrows(out, 1);
res=zeros(size(out));
for l = 2 : size(out, 1)
if out(l, 1) == out(l - 1, 1)
res(l-1,1) = out(l-1,1);
res(l-1,2) = out(l-1,2)+out(l,2);
else
res(l,1) = out(l,1);
res(l,2) = out(l,2);
end
end
[num idx] = max(res(:,2));
[x y] = ind2sub(size(res),idx);
segimg(i,j)=res(x,y)/10;
end
end
the segment result :http://i45.tinypic.com/2aj9mg.jpg
I am working on image processing. I want to add the difference of pixels of two images.
Suppose I have two images A, and B. I pick the first pixel of both images and store the difference value. I want to add this difference value to next pixel-difference. I try using this code, but it is not working. How can I do it?
A = imread('sub2.jpg');
B = imread('sub1.jpg');
tic
[rows cols] = size(A);
diff1 = 0;
for x = 1:rows
for y = 1:cols
diff = A(x,y)-B(x,y);
diff1 = diff1+diff;
end
end
disp(diff1);
toc
You can do it in one line as follows:
sum(sum(imsubtract(A-B)))
imsubtract subtracts two images and saves the difference in a matrix with the same size as A. Then, sum takes the sum of the result.
If you need absolute differences, you may use imabsdiff instead of imsubtract.
Note that the values of the differences are in 0 and 255. If you want negative instances, then you should directly subtract the matrices as A-B.
Looks okay though, but you're better off with:
diff1 = sum(sum(A-B));
or if B is larger than A:
diff1 = sum(sum(A-B(1:size(A,1),1:size(A,2))));
This gives just one value (as your code does), I'm not sure if that really is what you want..
How can I select some parts of an matrix and cut the single dimensions?
Example: B = zeros(100,100,3,'double');
When I select B(2,3,:) I get a 1x1x3 matrix as result - this is not the expected result, because for some operations (like norm) I need a vector as result. To handle this problem I used squeeze, but this operations seems to be very time consuming, especially when heavily used.
How can I select only the vector and 'cut' the single dimensions?
In your case you could use the colon operator, like this:
x = B(2,3,:);
x = x(:);
This places all elements of X into a number-of-elements by 1 vector.
You could also permute the dimensions to bring the non-singleton one to front. Either:
>> permute(B(2,3,:),[3 1 2])
ans =
0.97059
0.69483
0.2551
or
>> permute(B(2,3,:),[1 3 2])
ans =
0.97059 0.69483 0.2551
depending on whether you want a row or a column vector.