how to make smooth and remove the white edge? Besides, why the black lines arise in my answer? How to solve it? - image

Based on Shai and Biguri's codes and comments, I have finished a color picture like this:
A problem arises, how to remove the white edge and make it smooth? One solution may be to build 3x3 matrix or bigger and average. But the calculations should be large for every white-edge points. Or there may be some useful functions in Matlab to deal well with this problems?

If you have a license for the image processing toolbox, you can try using for example medfilt2 to apply a median filter on the image. A 11 by 11 median filter should do the trick. It is not very difficult to reimplement the filter yourself if you don't have the toolbox.
This is just one of the possibilities, you can use many different filters that will have different impacts on sharpness ang edge removal.
Edit:
Here is a quick median filter implementation (it may contain errors and could be optimized):
function ret = imageMedianFilter(im, np)
if(size(np,2) == 1)
npx = np;
npy = np;
else
npx = np(1);
npy = np(2);
end
ret = zeros(size(im,1),size(im,2));
for xpos = 1:size(im,1)
for ypos = 1:size(im,2)
curval = double(0);
if(xpos + npx - 1) > size(im,1)
npixels_x = size(im,1) - xpos + 1;
else
npixels_x = npx;
end
if(ypos + npy - 1) > size(im,2)
npixels_y = size(im,2) - ypos + 1;
else
npixels_y = npy;
end
a = im(xpos:xpos+npixels_x-1 , ypos:ypos+npixels_y-1);
a = reshape(a,1,size(a,1)*size(a,2));
curval = median(a);
ret(xpos , ypos) = curval;
end
end
ret = uint8(ret);
end
You can use it on R,G and B components as shown by Rotem below:
RGB = cat(3, imageMedianFilter(RGB(:,:,1), [11,11]), imageMedianFilter(RGB(:,:,2), [11,11]), imageMedianFilter(RGB(:,:,3), [11,11]));
(assuming your image is named RGB).

Here is my solution. I take n*n patch to average the near RGB. But there is a problem arising. Why the right down side of processed picture showing black lines?
clc;clf;close all;clear all;
img = imread('sample2color_t1.bmp'); %// read image
bw = img(:,:,1) > 128; %// convert to binary mask
[lb,lab] = bwlabel(bw,4); %// extract distinct regions
[a,b,c]=size(img);
R=ones(a,b);
G=ones(a,b);
B=ones(a,b);
%I have omitted other colors process codes. Below it is the white edges code.
r=[];c=[];
[r,c] = find(lb ==0);
for i=1:length(r)
R(r(i),c(i))=1;
G(r(i),c(i))=1;
B(r(i),c(i))=1;
end
scale=5;%步长1,8连通
for i=1:length(r)
sumR=0;sumG=0;sumB=0;
for j=0:2*scale
for k=0:2*scale
sumR=sumR+R(r(i)-scale+j,c(i)-scale+k);
sumG=sumG+G(r(i)-scale+j,c(i)-scale+k);
sumB=sumB+B(r(i)-scale+j,c(i)-scale+k);
end
end
R(r(i),c(i))=sumR/(2*scale+1)^2;
G(r(i),c(i))=sumG/(2*scale+1)^2;
B(r(i),c(i))=sumB/(2*scale+1)^2;
end
imPaint=cat(3,R,G,B);
figure;
imshow(imPaint);

Related

Detection of pellet on petri dish

I am currently doing a project on morphology of filamentous fungi during batch fermentation (Yes, I am not a software engineer.. Biotech). Where I am taken pictures of the morphology in a petri dish. I am developing a "fast" method to describe the pellets (small aggregates of fungi) that occurs during the fermentation. To do this I am writing a code in MatLab.
Depending on the color of the pellets (light or dark) the pictures are taken on differen backgrounds, black or white. I am inverting the picture if the mean gray value is below 70 to distinguish between backgrounds.
Pictures:
White background
Dark background
I have several problems:
Detecting the edge of the petri dish so it won't be regarded as an object (Currently done with the edge('log',) function). The edge is detected, but i miss some parts, think because of the lower light in top.
Proper thresholding inside the dish
Detection of pellets - right now it is done by a combination of running through each color channel, but might be done with some blob detection?
Does anybody have some inputs?
My code is as following:
close all
clear all
clc
%Empty arrays to hold data
metricD=[];
areaD=[];
perimeterD=[];
% Specify the folder where the files live.
myFolder = pwd;
% Check to make sure that folder actually exists. Warn user if it doesn't.
if ~isdir(myFolder)
errorMessage = sprintf('Error: The following folder does not exist:\n%s', myFolder);
uiwait(warndlg(errorMessage));
return;
end
% Get a list of all files in the folder with the desired file name pattern.
filePattern = fullfile(myFolder, '*.jpg'); % Change to whatever pattern you need.
theFiles = dir(filePattern);
% Show debugging plots
plotFig = 0;
% parameters that can be tuned
% how many colors channels we minimum want to see a spore in
% e.g. set to 1 for image "P. f Def C.tif"
labelcutOff = 1;
% remove areas larger than
removeLargerthan = 500000;
for k = 1 : length(theFiles)
baseFileName = theFiles(k).name;
fullFileName = fullfile(myFolder, baseFileName);
%% reading as an image array with im
I = imread(fullFileName);
% convert to grayscale
Ig = rgb2gray(I);
if plotFig
figure;imagesc(I)
figure;imagesc(Ig)
end
mm=mean(mean(Ig));
if mm < 70
I=imcomplement(I);
Ig = imcomplement(Ig);
end
% BLOB DETCTION
% h = fspecial('log', [15 15], 2);
% imLOG = imfilter(Ig, h);
% figure;imagesc(imLOG)
%% find petridish by edges and binary operations
% HACK - NOT HOW IT SHOULD BE DONE
Ig = wiener2(Ig,[5 5]);
imEdge = edge(Ig,'log');
circle = bwareaopen(imEdge,50);
circle = imclose(circle,strel('disk',30));
circle = bwareaopen(circle,8000);
% circle = imfill(circle,'holes');
circle = bwconvhull(circle);
circle = imerode(circle,strel('disk',150));
if plotFig
figure;imagesc(circle)
end
%% Get thresholds inside dish using otsu on each channel
imR = double(I(:,:,1)) .* circle;
imG = double(I(:,:,2)) .* circle;
imB = double(I(:,:,3)) .* circle;
thresR = graythresh(uint8(imR(circle))) *max(imR(circle));
thresG = graythresh(uint8(imG(circle))) *max(imG(circle));
thresB = graythresh(uint8(imB(circle))) *max(imB(circle));
if plotFig
figure;imagesc(imR)
figure;imagesc(imG)
figure;imagesc(imB)
end
%% classify inside dish
% check if it should be smaller or larger than
if sum(imR(circle) < thresR) > sum(imR(circle) > thresR)
labelR = imR > thresR;
else
labelR = imR < thresR;
end
if sum(imG(circle) < thresG) > sum(imG(circle) > thresG)
labelG = imG > thresG;
else
labelG = imG < thresG;
end
if sum(imB(circle) < thresB) > sum(imB(circle) > thresB)
labelB = imB > thresB;
else
labelB = imB < thresB;
end
if plotFig
figure;imagesc(labelR)
figure;imagesc(labelG)
figure;imagesc(labelB)
end
labels = (labelR + labelG + labelB) .* circle;
labels(labels < labelcutOff) = 0;
labels = imfill(labels,'holes');
labels = bwareaopen(labels,30);
if plotFig
figure;imagesc(labels)
end
%% clean up labels
labelBig = bwareaopen(labels,removeLargerthan);
labels = labels - labelBig;
if plotFig
figure;imagesc(labels)
end
BN = labels;
%% old script
stats = regionprops(BN,'Basic');
obj2 = numel(stats);
[B,L] = bwboundaries(BN,'holes');
figure
% imshow(label2rgb(L, #jet, [.5 .5 .5]))
imshow(I)
hold on
title(baseFileName)
for j = 1:length(B)
boundary = B{j};
plot(boundary(:,2), boundary(:,1),'w','LineWidth',2)
end
%region stats
stats = regionprops(L,'Area','Centroid');
%Threshold for printing in end
threshold = 0.2;
%Conversion factor pixel to cm
conversionF=9/2125;
% loop over the boundaries
for j = 1:length(B)
% obtain (X,Y) boundary coordinates corresponding to label 'j'
boundary = B{j};
% compute a simple estimate of the object's perimeter
delta_sq = diff(boundary).^2;
perimeter = sum(sqrt(sum(delta_sq,2)));
perimeterD(j,k)=perimeter*conversionF;
% obtain the area calculation corresponding to label 'k'
area = stats(j).Area;
areaD(j,k)=area*conversionF^2;
% compute the roundness metric
metric = 4*pi*area/perimeter^2;
metricD(j,k)=metric;
% display the results
metric_string = sprintf('%d. %2.2f', j,metric);
text(boundary(1,2)-50,boundary(1,1)+23,metric_string,'Color','k',...
'FontSize',14,'FontWeight','bold');
end
drawnow; % Force display to update immediately.
end
%Calculating stats
areaM=mean(areaD);
pM=mean(perimeterD);
metricD(metricD==Inf)=0;
mM=mean(metricD);
Hint:
A morphological top-hat filter fllowed by binarization (with a constant threshold ?) can be a good start. And filtering on the blob size will do a reasonable cleanup.
For the edges, try circular Hough.

To show/join Two Images Simultaneously in Matlab's slider?

I cannot make too big file (like tried here) so I need to show only portions at a time.
However, I cannot make the transfer from one file to another smooth in Matlab.
I am trying to expand the solution of the thread To refresh imshow in Matlab? for two images. The problem is the ending of image A and start of the image B. Now, I have an interruption in the flow, which I do not like because I cannot show two images at the same time without an interruption.
In the example here, it is not needed to filter the axes.
Code
iterationCounter=1;
hFig=figure('Menubar','none', 'NumberTitle','off', 'Color','k');
while(iterationCounter < 7)
filenamePng=fullfile(homedir, '/Images/Raw/', iterationCounter, '.png');
imgRGB=imread(filenamePng);
% https://stackoverflow.com/a/29952648/54964
%%// create sliding-window video
len = 40*2^3;
signal = imgRGB(:,1:end,:);
hImg = imshow(signal(:,1:1+len,:), ...
'InitialMagnification',100, 'Border','tight');
vid = VideoWriter('signal.avi');
vid.Quality = 100;
vid.FrameRate = 60;
open(vid);
M = size(signal,2);
for k=1:M-len
set(hImg, 'CData',signal(:,k:k+len,:))
writeVideo(vid, getframe());
end
iterationCounter=iterationCounter+1;
end
close(vid);
Output for Image A and Image B
where there is an interruption in the slider after each image.
The picture is just a screenshot of two images: beginning and ending of the slider. The blue area is just OS X GUI but still indicates that there is a gap and interruption between the start and end.
How can show/join two images simultaneously in Matlab's slider?
In order to display multiple images side by side in this scrolling window, I think the easiest approach is to actually load all of the images upfront into an array that is [nRows x (nColumns * nImages) x 3] and then just use the original code to scroll through this.
hFig=figure('Menubar','none', 'NumberTitle','off', 'Color','k');
signal = [];
% Load all the images into one "long" image
for k = 1:7
filename = fullfile(homedir, sprintf('%d.png', k));
img = imread(filename);
signal = cat(2, signal, img);
end
%%// create sliding-window video
windowWidth = 320; % Width in pixels
hImg = imshow(signal(:,1:1 + windowWidth,:), ...
'InitialMagnification',100, 'Border','tight');
vid = VideoWriter('signal.avi');
vid.Quality = 100;
vid.FrameRate = 60;
open(vid);
M = size(signal,2);
for k = 1:(M - windowWidth)
set(hImg, 'CData',signal(:,k:k + windowWidth,:))
writeVideo(vid, getframe());
end
close(vid);
The command imagesc is a low-level image command where Suever's proposal does not work.
A general approach to remove padding/margins/background is to use
<plot imshow imagesc ...>
set(gca,'position',[0 0 1 1],'units','normalized')

Image with accordion effect

I have read in an image file to MATLAB and I am trying to stretch it in one direction, but a variable amount (sinusoidal). This would create an accordion affect on the image. I have toyed around with imresize, however that only resizes the image linearly. I would like the amount of "stretch" to vary for each image line. I tried to convey this with the following code:
periods = 10; % Number of "stretch" cycles
sz = size(original_image,2)/periods;
s = 0;
x = 0;
for index = 1:periods
B = original_image(:,round(s+1:s+sz));
if mod(index,2) == 0
amp = 1.5;
else
amp = 0.75;
end
xi = size(B,2)*amp;
new_image(:,x+1:x+xi) = imresize(B, [size(B,1) size(B,2)*amp]);
s = s + sz;
x = x+xi;
end
You can see that segments of the image are stretched, then compressed, then stretched, etc, like an accordion. However, each segment has a uniform amount of stretch, whereas I'd like it to be increasing then decreasing as you move along the image.
I have also looked at MATLAB's example of Applying a Sinusoidal Transformation to a Checkerboard which seems very applicable to my problem, however I have been trying and I cannot get this to produce the desired result for my image.
Any help is much appreciated.
UPDATE:
Thank you for Answer #1. I was unable to get it to work for me, but also realized it would resulted in loss of data, as the code only called for certian lines in the original image, and other lines would have been ignored.
After experimenting further, I developed the code below. I used a checkerboard as an example. While combersome, it does get the job done. However, upon trying the script with an actual high-resolution image, it was extremely slow and ended up failing due to running out of memory. I believe this is because of the excessive number of "imresize" commands that are used in loop.
I = checkerboard(10,50);
I = imrotate(I,90);
[X Y] = size(I);
k = 4; % Number of "cycles"
k = k*2;
x = 1;
y = 2;
z = 2;
F = [];
i = 1;
t = 0;
s = 0;
for j = 1:k/2
t = t + 1;
for inc = round(s+1):round(Y/k*t)
Yi = i + 1;
F(:,(x:y)) = imresize(I(:,(inc:inc)),[X Yi]);
x = y + 1;
y = x + z;
z = z + 1;
i = i + 1;
end
y = y - 2;
z = z - 4;
for inc = round(Y/k*t+1):round(Y/k*(t+1))
Yi = i - 1;
F(:,(x:y)) = imresize(I(:,(inc:inc)),[X Yi]);
x = y + 1;
y = x + z;
z = z - 1;
i = i - 1;
end
y = y + 2;
z = z + 4;
s = Y/k*(t+1);
t = t + 1;
end
Fn = imresize(F, [X Y]);
imshow(Fn);
Does anyone know of a simpler way to achieve this? If you run the code above, you can see the effect I am trying to achieve. Unfortunately, my method above does not allow me to adjust the amplitude of the "stretch" either, only the number of "cycles," or frequency. Help on this would also be appreciated. Much thanks!
Here is how I would approach it:
Determine how the coordinate of each point in your Final image F maps into your Initial image I of size (M,N)
Since you want to stretch horizontally only, given a point (xF,yF) in your final image, that point would be (xI,yI) in your initial image where xI and yI can be obtained as follows:
yI = yF;
xI = xF + Lsin(xFK);
Notes:
these equations do not guarantee that xI remains within the range [1:N] so cropping needs to be added
K controls the how many wrinkles you want to have in your accordion effect. For example, if you only want one wrinkle, K would be 2*pi/N
L controls how much stretching you want to apply
Then simply express your image F from image I with the transforms you have in 1.
Putting it all together, the code below creates a sample image I and generates the image F as follows:
% Generate a sample input image
N=500;
xF=1:N;
I=(1:4)'*xF/N*50;
% Set the parameters for your accordion transform
K=2*pi/N;
L=100;
% Apply the transform
F=I(:, round(min(N*ones(1,N), max(ones(1,N), (xF + L*sin(xF*K))))) );
% Display the input and output images side by side
image(I);
figure;
image(F);
If you run this exact code you get:
As you can see, the final image on the right stretches the center part of the image on the left, giving you an accordion effect with one wrinkle.
You can fiddle with K and L and adjust the formula to get the exact effect you want, but note how by expressing the transform in a matrix form MATLAB executes the code in a fraction of second. If there is one take away for you is that you should stay away from for loops and complex processing whenever you can.
Have fun!

Separating Background and Foreground

I am new to Matlab and to Image Processing as well. I am working on separating background and foreground in images like this
I have hundreds of images like this, found here. By trial and error I found out a threshold (in RGB space): the red layer is always less than 150 and the green and blue layers are greater than 150 where the background is.
so if my RGB image is I and my r,g and b layers are
redMatrix = I(:,:,1);
greenMatrix = I(:,:,2);
blueMatrix = I(:,:,3);
by finding coordinates where in red, green and blue the values are greater or less than 150 I can get the coordinates of the background like
[r1 c1] = find(redMatrix < 150);
[r2 c2] = find(greenMatrix > 150);
[r3 c3] = find(blueMatrix > 150);
now I get coordinates of thousands of pixels in r1,c1,r2,c2,r3 and c3.
My questions:
How to find common values, like the coordinates of the pixels where red is less than 150 and green and blue are greater than 150?
I have to iterate every coordinate of r1 and c1 and check if they occur in r2 c2 and r3 c3 to check it is a common point. but that would be very expensive.
Can this be achieved without a loop ?
If somehow I came up with common points like [commonR commonC] and commonR and commonC are both of order 5000 X 1, so to access this background pixel of Image I, I have to access first commonR then commonC and then access image I like
I(commonR(i,1),commonC(i,1))
that is expensive too. So again my question is can this be done without loop.
Any help would be appreciated.
I got solution with #Science_Fiction answer's
Just elaborating his/her answer
I used
mask = I(:,:,1) < 150 & I(:,:,2) > 150 & I(:,:,3) > 150;
No loop is needed. You could do it like this:
I = imread('image.jpg');
redMatrix = I(:,:,1);
greenMatrix = I(:,:,2);
blueMatrix = I(:,:,3);
J(:,:,1) = redMatrix < 150;
J(:,:,2) = greenMatrix > 150;
J(:,:,3) = blueMatrix > 150;
J = 255 * uint8(J);
imshow(J);
A greyscale image would also suffice to separate the background.
K = ((redMatrix < 150) + (greenMatrix > 150) + (blueMatrix > 150))/3;
imshow(K);
EDIT
I had another look, also using the other images you linked to.
Given the variance in background colors, I thought you would get better results deriving a threshold value from the image histogram instead of hardcoding it.
Occasionally, this algorithm is a little to rigorous, e.g. erasing part of the clothes together with the background. But I think over 90% of the images are separated pretty well, which is more robust than what you could hope to achieve with a fixed threshold.
close all;
path = 'C:\path\to\CUHK_training_cropped_photos\photos';
files = dir(path);
bins = 16;
for f = 3:numel(files)
fprintf('%i/%i\n', f, numel(files));
file = files(f);
if isempty(strfind(file.name, 'jpg'))
continue
end
I = imread([path filesep file.name]);
% Take the histogram of the blue channel
B = I(:,:,3);
h = imhist(B, bins);
h2 = h(bins/2:end);
% Find the most common bin in the *upper half*
% of the histogram
m = bins/2 + find(h2 == max(h2));
% Set the threshold value somewhat below
% the value corresponding to that bin
thr = m/bins - .25;
BW = im2bw(B, thr);
% Pad with ones to ensure background connectivity
BW = padarray(BW, [1 1], 1);
% Find connected regions in BW image
CC = bwconncomp(BW);
L = labelmatrix(CC);
% Crop back again
L = L(2:end-1,2:end-1);
% Set the largest region in the orignal image to white
for c = 1:3
channel = I(:,:,c);
channel(L==1) = 255;
I(:,:,c) = channel;
end
% Show the results with a pause every 16 images
subplot(4,4,mod(f-3,16)+1);
imshow(I);
title(sprintf('Img %i, thr %.3f', f, thr));
if mod(f-3,16)+1 == 16
pause
clf
end
end
pause
close all;
Results:
Your approach seems basic but decent. Since for this particular image the background is composed of mainly blue so you be crude and do:
mask = img(:,:,3) > 150;
This will set those pixels which evaluate to true for > 150 to 0 and false to 1. You will have a black and white image though.
imshow(mask);
To add colour back
mask3d(:,:,1) = mask;
mask3d(:,:,2) = mask;
mask3d(:,:,3) = mask;
img(mask3d) = 255;
imshow(img);
Should give you the colour image of face hopefully, with a pure white background. All this requires some trial and error.

Ellipse Detection using Hough Transform

using Hough Transform, how can I detect and get coordinates of (x0,y0) and "a" and "b" of an ellipse in 2D space?
This is ellipse01.bmp:
I = imread('ellipse01.bmp');
[m n] = size(I);
c=0;
for i=1:m
for j=1:n
if I(i,j)==1
c=c+1;
p(c,1)=i;
p(c,2)=j;
end
end
end
Edges=transpose(p);
Size_Ellipse = size(Edges);
B = 1:ceil(Size_Ellipse(1)/2);
Acc = zeros(length(B),1);
a1=0;a2=0;b1=0;b2=0;
Ellipse_Minor=[];Ellipse_Major=[];Ellipse_X0 = [];Ellipse_Y0 = [];
Global_Threshold = ceil(Size_Ellipse(2)/6);%Used for Major Axis Comparison
Local_Threshold = ceil(Size_Ellipse(1)/25);%Used for Minor Axis Comparison
[Y,X]=find(Edges);
Limit=numel(Y);
Thresh = 150;
Para=[];
for Count_01 =1:(Limit-1)
for Count_02 =(Count_01+1):Limit
if ((Count_02>Limit) || (Count_01>Limit))
continue
end
a1=Y(Count_01);b1=X(Count_01);
a2=Y(Count_02);b2=X(Count_02);
Dist_01 = (sqrt((a1-a2)^2+(b1-b2)^2));
if (Dist_01 >Global_Threshold)
Center_X0 = (b1+b2)/2;Center_Y0 = (a1+a2)/2;
Major = Dist_01/2.0;Alpha = atan((a2-a1)/(b2-b1));
if(Alpha == 0)
for Count_03 = 1:Limit
if( (Count_03 ~= Count_01) || (Count_03 ~= Count_02))
a3=Y(Count_03);b3=X(Count_03);
Dist_02 = (sqrt((a3 - Center_Y0)^2+(b3 - Center_X0)^2));
if(Dist_02 > Local_Threshold)
Cos_Tau = ((Major)^2 + (Dist_02)^2 - (a3-a2)^2 - (b3-b2)^2)/(2*Major*Dist_02);
Sin_Tau = 1 - (Cos_Tau)^2;
Minor_Temp = ((Major*Dist_02*Sin_Tau)^2)/(Major^2 - ((Dist_02*Cos_Tau)^2));
if((Minor_Temp>1) && (Minor_Temp<B(end)))
Acc(round(Minor_Temp)) = Acc(round(Minor_Temp))+1;
end
end
end
end
end
Minor = find(Acc == max(Acc(:)));
if(Acc(Minor)>Thresh)
Ellipse_Minor(end+1)=Minor(1);Ellipse_Major(end+1)=Major;
Ellipse_X0(end+1) = Center_X0;Ellipse_Y0(end+1) = Center_Y0;
for Count = 1:numel(X)
Para_X = ((X(Count)-Ellipse_X0(end))^2)/(Ellipse_Major(end)^2);
Para_Y = ((Y(Count)-Ellipse_Y0(end))^2)/(Ellipse_Minor(end)^2);
if (((Para_X + Para_Y)>=-2)&&((Para_X + Para_Y)<=2))
Edges(X(Count),Y(Count))=0;
end
end
end
Acc = zeros(size(Acc));
end
end
end
Although this is an old question, perhaps what I found can help someone.
The main problem of using the normal Hough Transform to detect ellipses is the dimension of the accumulator, since we would need to vote for 5 variables (the equation is explained here):
There is a very nice algorithm where the accumulator can be a simple 1D array, for example, and that runs in . If you wanna see code, you can look at here (the image used to test was that posted above).
If you use circle for rough transform is given as rho = xcos(theta) + ysin(theta)
For ellipse since it is
You could transform the equation as
rho = axcos(theta) + bysin(theta)
Although I am not sure if you use standard Hough Transform, for ellipse-like transforms, you could manipulate the first given function.
If your ellipse is as provided, being a true ellipse and not a noisy sample of points;
the search for the two furthest points gives the ends of the major axis,
the search for the two nearest points gives the ends of the minor axis,
the intersection of these lines (you can check it's a right angle) occurs at the centre.
If you know the 'a' and 'b' of an ellipse then you can rescale the image by factor of a/b in one direction and look for circle. I am still thinking about what to do when a and b are unknown.
If you know that it is circle then use Hough transform for circles. Here is a sample code:
int accomulatorResolution = 1; // for each pixel
int minDistBetweenCircles = 10; // In pixels
int cannyThresh = 20;
int accomulatorThresh = 5*_accT+1;
int minCircleRadius = 0;
int maxCircleRadius = _maxR*10;
cvClearMemStorage(storage);
circles = cvHoughCircles( gryImage, storage,
CV_HOUGH_GRADIENT, accomulatorResolution,
minDistBetweenCircles,
cannyThresh , accomulatorThresh,
minCircleRadius,maxCircleRadius );
// Draw circles
for (int i = 0; i < circles->total; i++){
float* p = (float*)cvGetSeqElem(circles,i);
// Draw center
cvCircle(dstImage, cvPoint(cvRound(p[0]),cvRound(p[1])),
1, CV_RGB(0,255,0), -1, 8, 0 );
// Draw circle
cvCircle(dstImage, cvPoint(cvRound(p[0]),cvRound(p[1])),
cvRound(p[2]),CV_RGB(255,0,0), 1, 8, 0 );
}

Resources