MATLAB - How to measure mean intensity of a circular area in an image? [duplicate] - matlab

This question already has answers here:
mean value in a sphere
(3 answers)
Closed 5 years ago.
I want the mean intensity of an image, not the whole but only in a certain region of interest. This happens to be circular in shape and I know details of its radius and position.
Just inside the circular ROI (circle not drawn, using the radius and position). I dont want to mask the image and delete the outsides because that'll add unnecessary datapoints to the average.

You can use Boolean indexing
% creating the image:
[xx, yy] = meshgrid(1:100);
r = 23; x0 = 45; y0 = 67;
pixelsInSphere = ((xx-x0).^2 + (yy-y0).^2 < r);
im = pixelsInSphere.*(128+10*randn(size(yy)));
figure; imagesc(im);
% calculating the mean of the pixels using boolean indexing:
m = mean(im(pixelsInSphere));

You can create an Indicator function which given a position of pixel (i, j) it will say whether it is inside the ROI or not.
Loop over all the pixel in the image.
Sum the pixels which are in the ROI according to the indicator.

Related

How to find a brightest point an image and mark it in Matlab? [duplicate]

This question already has an answer here:
How to find and highlight the brightest region an image in Matlab?
(1 answer)
Closed 1 year ago.
Dears,
I would like to ask you for help with the code. My goal is to find the brightest point an image and mark it.
I used the following code to get the Image in Grey Values -> How to find and highlight the brightest region an image in Matlab? and tried to extend it based on my intention.
Then I found the max value of the matrix and go with the for loop function to highlight the coordinates of the max points. Unfortunately, here I have started struggle.
rgbImage = imread( 'Zoom1_WhiteImage.png' );
%imshow(rgbImage);
[rows, columns, numberOfColorChannels] = size(rgbImage)
if numberOfColorChannels == 1
brightness = rgbImage; % For a 1 channel image, brightness is the same as the original pixel value.
else
% For an RGB image, the brightness can be estimated in various ways, here's one standard formula:
brightness = (0.2126*rgbImage(:, :, 1) + 0.7152*rgbImage(:, :, 2) + 0.0722*rgbImage(:, :, 3));
end
% Establish a brightness threshold - pixels brighter than this value will
% be highlighted
threshold = 105;
% Create a zero-filled mask of equal size to the image to hold the
% information of which pixels met the brightness criterion:
mask = zeros(rows, columns, 'logical');
% Assign "1" to any mask pixels whose corresponding image pixel met the
% brightness criterion:
mask(brightness > threshold) = 1;
[a,b] = size(brightness)
maxgrey = max(max(brightness));
aux=0;
for i=1:1:a;
for j=1:1:b;
if brightness(a,b)>brightness(a,b+1)
aux=brightness(a,b+1)
else aux
end
end
end
Could you help me to finish the code, please?
You can achieve your goal with the function find() or with the function ind2sub():
% Random 2D matrix
I = rand(10);
% First option with find
[x,y] = find(I == max(I(:)))
% Second option using ind2sub, a bit more efficient since we only read I once.
[~,ind] = max(I(:))
[x,y] = ind2sub(size(I),ind)

Remove overlapped Circles in MATLAB [duplicate]

This question already has answers here:
Non overlapping randomly located circles
(4 answers)
Closed 5 years ago.
I have written a MATLAB code to be able to visualize some Circles. Please have a look at my below code and the attached figure as the output.
clc;
clear;
close all;
% X and Y of each Center
Xloc = [1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5];
Yloc = [1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5];
% Radius of each circle
radius = unifrnd(0,1,[1 numel(Xloc)]);
% Random colours
allColours = rand(numel(Xloc),3);
% Transform the data into position = [left bottom width height]
pos = [Xloc(:)-radius(:) Yloc(:)-radius(:) 2*radius(:)*[1 1]];
% Create and format the axes
H = axes;
hold on;
axis equal;
box on;
set(H,'XTickLabel',[],'YTickLabel',[]);
% Create the circles
for idx = 1:numel(Xloc);
rectangle(...
'Position',pos(idx,:),...
'Curvature',[1 1],...
'FaceColor',allColours(idx,:),...
'EdgeColor','none');
end
The output figure is (Circles' radius is generated randomly, so if you execute the code, you will face with a new output):
As you can see in the figure, there is overlap between circles. I was wondering how can I separate centers from each other to do not overlap each others, and at the same time they keep the original distance (or similar distance) from each other in [Xloc Yloc]
You can try to formulate an optimisation problem:
You have to constrain the minimal distance between the centers based on the desired radii.
You have to minimise the deviations from its desired center location.

extracting coordinates from gray scales photos

Hi I am trying to extract x,y coordinates from gray scale photo (example.jpg).
I mark the points (with red dots) where I want the x, y coordinates (example1.jpg)
Then I extract the red dots area with below codes
A=imread('example.jpg');
B=imread('example1.jpg');
Size=size(A)
C=zeros(Size);
for j=1:Size(2)
for i=1:Size(1)
if A(i,j)==B(i,j);
C(i,j)=1;
else C(i,j)=255;
end
end
end
K=mat2gray(C);
imshow(K)
By doing this, I can extract the dots (I am interested) and got below image but the dot points bigger than my real marking in the photo (dots.png). And it did not capture all dots (8 out of 10 dots)
Then to get the x,y coordinates of these dot points, I use below codes:
X=imread('dots.png');
[I,J] = find(X(:,:,1) == 255); %// Change
scatter(I,J)
Then I got x and y coordinates in terms of I,J and the picture to counter check if the coordinates show the correct positions as in the photo.
But here are the problems I need solve:
1) How can I get the smaller dot points in figure 3 (as the dot I mark in gray photos are small but when it is generated in figure 3, it become bigger. As a consequence, when I extract x,y coordinates (in terms of I,J here), I got multiple x and y for one dot as each dot is so big. Instead, I want to get one x and one y for each dot.
2) How to make to capture all dots that I mark
3) And when you look at the figure 3 and 4, figure 3 shows the real orientation of pumpkin but in the figure 4, it is rotated. How this happen and how can I correct it?
4) And I thought there can be an easier way to do this extraction than my method. Can you please advice?
Thank you
Here's a more complete example, for the sake of an answer:
I = imread('cameraman.tif');
figure, imshow(I)
[y, x] = ginput(5); % This chooses the five points interactively.
close
color = I; % making a RGB color version of the image.
color(:,:,2) = I;
color(:,:,3) = I;
for idx = 1:numel(x)
% Change the color of the points to red one by one.
xpoint = x(idx);
ypoint = y(idx);
color(xpoint, ypoint, 1) = 255;
color(xpoint, ypoint, 2) = 0;
color(xpoint, ypoint, 3) = 0;
end
figure,
imshow(color) % display the colored dot image.
This should select five points in the image, interactively, and then color those points red.
In terms of the blobs I suggest that you have saved the image with the red dots using a compressed file format.
The blobs seem to be 24x24 macroblocks - not sure what compression algorithm uses that (not jpeg)...
Here it is one up close:
Regardless, an easy way to see why it is happening is to list the values of A(i,j) and B(i,j) when A(i,j) != B(i,j) - a basic bug finding process you can do yourself.

Count black pixels within a circle [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I have one vector of radii and second vector of hundreds of [X,Y] coordinates. For each possible coordinate-radius pair I have count all black pixels within a circle (whose center is placed in the coordinate) on an input binary image.
What is the fastest way to do it? My only idea is to iterate through every pixel of an image, check the circle equation and then the pixel color but it doesn't seem much optimized for several hundred such operations.
Matlab is great for working with images thanks to the matrix syntax. It does also work with indices so most time you can avoid "iterating through pixels" (although sometimes you'll still have to).
Instead of checking all the pixels within each circle, and having to detect how many pixels were counted twice, another approach is to create a mask, the same size of you image. Blank this mask for each of your circles (so overlapping pixels are only 'blanked' once), then apply the mask on your original picture and count the remaining illuminated pixels.
For an example, I have to take some sample data, the image:
load trees
BW = im2bw(X,map,0.4);
imshow(BW)
And 20 random point/circle coordinates (you can change the number of points and the min/max radii easily):
%// still building sample data
s = size(BW) ;
npt = 20 ; Rmin=5 ; Rmax=20 ; %// problem constants
x = randi([1 s(2)] ,npt,1); %// random X coordinates
y = randi([1 s(1)] ,npt,1); %// Y
r = randi([Rmin Rmax],npt,1); %// radius size between 5 to 20 pixels.
Then we build your custom mask :
%// create empty mask with enough overlap for the circles on the border of the image
mask = false( s+2*Rmax ) ;
%// prepare grid for a sub-mask of pixels, as wide as the maximum circle
xmask = -Rmax:Rmax ;
[xg,yg] = ndgrid(xmask,xmask) ;
rg = sqrt( (xg.^2+yg.^2) ) ; %// radius of each pixel in the subgrid
for ip=1:npt
mrow = xmask+Rmax+y(ip) ; %// calc coordinates of subgrid on original mask
mcol = xmask+Rmax+x(ip) ; %// calc coordinates of subgrid on original mask
cmask = rg <= r(ip) ; %// calculate submask for this radius
mask(mrow,mcol) = mask(mrow,mcol) | cmask ; %// apply the sub-mask at the x,y coordinates
end
%// crop back the mask to image original size (=remove border overlap)
mask = mask(Rmax+1:end-Rmax,Rmax+1:end-Rmax) ;
imshow(mask)
Then you just apply the mask and count :
%% // Now apply on original image
BWm = ~BW & mask ; %// note the ~ (not) operator because you want the "black" pixels
nb_black_pixels = sum(sum(BWm)) ;
imshow(BWm)
nb_black_pixels =
5283
Here is one implementation:
Advantages:
No loops, meshgrid/ndgrid. Instead used faster bsxfun and pdist2
Dots are counted only once, even when the circles overlap.
Variable radius used (radius of all circle is not same)
Code:
%// creating a binary image with little black dots
A = randi(600,256);
imbw = A ~= 1;
%// Your binary image with black dots
imshow(imbw);
%// getting the index of black dots
[dotY, dotX] = find(~imbw);
nCoords = 10; %// required number of circles
%// generating its random coordinates as it is unknown here
Coords = randi(size(A,1),nCoords,2);
%// calculating the distance from each coordinate with every black dots
out = pdist2(Coords,[dotX, dotY]).'; %//'
%// Getting only the black dots within the radius
%// using 'any' avoids calculating same dot twice
radius = randi([10,25],1,size(Coords,1));
pixelMask = any(bsxfun(#lt, out, radius),2);
nPixels = sum(pixelMask);
%// visualizing the results by plotting
hold on
scatter(dotX(pixelMask),dotY(pixelMask));
viscircles([Coords(:,1),Coords(:,2)],radius.'); %//'
hold off
Output:
>> nPixels
nPixels =
19

Get the matrix after imagesc? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
imagesc plot to matrix in matlab
Scale Matrix to a new range
I have:
I = imread('image.tif');
At this point I can easly print the pixel with cord 100,100 by doing I(100,100)
Now I scale to image to fit the range 0.5...0.9
imagesc(I,[0.5 0.9]);
colormap('gray');
Is there any way to get the new matrix I ? (with pixel values from 0.5 to 0.9)
If i do
I = imagesc(I,[0.5 0.9]);
I only get the handler to image object
You can get the image data from an image plot with:
A = rand(100,100);
I = imagesc(A, [.5 .9]);
B = get(I, 'CData');
Predicting from your previous question: Scale Matrix to a new range I expect that B won't be you want. In fact B will be identical to A. This can be verified with:
all(all(A==B))
The second argument to imagesc doesn't scale the values in the provided matrix rather it scales the colormap.
Try the getimage command:
A = rand(100,100);
I = imagesc(A, [.5 .9]);
B = getimage(gca);