MATLAB: Hello i need clearer circle after performing the below code help me plz

Image Processing Toolboxmatlab circletree rings

clear all
close all
[FileName,PathName] = uigetfile('*.*','Select the image file');
nomfich=[PathName,FileName];
ima=imread(nomfich);
HSV=rgb2hsv(ima);
H=HSV(:,:,1);
S=HSV(:,:,2);
V=HSV(:,:,3);
%dilate image
SE = strel('line',1,1);
H = imdilate(H,SE);
S = imdilate(S,SE);
V = imdilate(V,SE);
%performing dwt2 on h,s,v channels
[hca1,hch1,hcv1,hcd1] = dwt2(H,'bior1.3');
[sca1,sch1,scv1,scd1] = dwt2(S,'bior1.3');
[vca1,vch1,vcv1,vcd1] = dwt2(V,'bior1.3');
%replacing ll(hac1) with adding all other three values(hch1,hcv1,hcd1). sililarly for s and v channls ll band is replaed with new value
LH=hch1+hcv1+hcd1;
LS=sch1+scv1+scd1;
LV=vch1+vcv1+vcd1;
reconstructing image using replaced ll value
a=idwt2(LH,hch1,hcv1,hcd1,'bior1.3');
%figure,imshow(a);
b=idwt2(LS,sch1,scv1,scd1,'bior1.3');
%figure,imshow(b);
c=idwt2(LV,vch1,vcv1,vcd1,'bior1.3');
%figure,imshow(c);
%hsvimg=a+b+c;
%combing all the three result into hsv1 image for display
HSV1(:,:,1)=a;
HSV1(:,:,2)=b;
HSV1(:,:,3)=c;
figure,imshow(HSV1);
title('reconstructed HSV image');
rgbimg=hsv2rgb(HSV1);
figure,imshow(rgbimg);
%imhist(rgbimg);
title('reconstructed rgb image');
grayimg=rgb2gray(rgbimg);
figure,imshow(grayimg);
%imhist(grayimg);
%perfotming otsu
level = graythresh(grayimg);
BW = im2bw(grayimg,level);
imshow(BW);

Best Answer

Hi Shivu Shetty
to acquire center and surface points on the image, use the attached ginputRed.m that has red crosshairs, as the standard ginput.m does not allow to change color, and there is no switch in figure, axes or plot handles to change crosshair color.
More images uploaded as soon as 10 uploads per day cap reloaded.
1.-
acquiring one of your start images:
clear all;close all;clc
A=imread('001.jpg');
A1=A(:,:,1); % A2=A(:,:,2);A3=A(:,:,3);
hf1=figure(1);imshow(A1);ax1=hf1.CurrentAxes;
% 002
2.-
adjusting contrast
A02=imadjust(A1,[.81;.89],[0;1]);
hf2=figure(2);h_im=imshow(A02);ax2=hf2.CurrentAxes;
% 003
3.-
trying surf
dx1=1;
[X,Y]=meshgrid([1:dx1:size(A1,2)],[1:1:size(A1,1)]);
surf(X,Y,255-A02,'EdgeColor','none')
% 004-1
.
.
surf has all rings clipping the roof of 255, which is good to count tree rings.
surf(255-A02) better than surf(A02)
.
.
yet one wonders if the rings could be a bit thicker to count them and if it is possible to have all rings with the highest amplitude, to avoid false counts, or missing rings
4.-
trying interpolation in case there's need for more samples
some ring peaks look too sharp with only one sample and many rings do really have a low level:
dx2=.1;
[Xq,Yq]=meshgrid([1:dx2:size(A1,2)],[1:dx2:size(A1,1)]);
A02q=interp2(X,Y,double(255-A02),Xq,Yq);
hf3=figure(3);surf(Xq,Yq,255-A02q,'EdgeColor','none');
comparing,
% 005
% 006
.
.
no discernible difference, still some peaks to sharp, some other peaks too low
5.-
let's carry on with fence-like rings as peaks, better than narrow trenches in A02
A03=A02q;
% 004-2
6.-
thresholding
there are some really low yet valid peaks too close to false peaks
A03(A03>=125)=255;A03(A03<125)=0;
7.-
trying single straight cross section, centre to outer crust
hf4=figure(4);hsf2=surf(Xq,Yq,A03,'EdgeColor','none');
ax4=hf4.CurrentAxes
ax4.DataAspectRatio=[1 6 1]
ax4.DataAspectRatio=[1 1 1]
campos(ax4,[250 250 3664])
how to fix ginput figure axes and plot handles not having switch for crosshair colour:
.
p=ginputRed(2)
p=floor(p)
nx=floor(linspace(p(1,1),p(2,1),max(abs(p(1,1)-p(2,1)),abs(p(1,2)-p(2,2)))))
ny=floor(linspace(p(1,2),p(2,2),max(abs(p(1,1)-p(2,1)),abs(p(1,2)-p(2,2)))))
hold(ax4,'on');plot(ax4,nx,ny,'r-');plot(ax4,[p(1,1) p(2,1)],[p(1,2) p(2,2)],'ro')
% 007
.
.
L=[];
for k=1:1:numel(nx)
L=[L A1(ny(k),nx(k))]
end
figure(5);plot(L);grid on
figure(6);plot(diff(L));grid on
.
cross sections shown in 005 and 006 above
it still doesn't get the count to the comfortable place where rings are clear tall peaks and everything else far enough below to avoid confusion.
Yet, surf has coloured the rings clearly yellow, away to everything else in magenta, let's exploit this
8.-
Isolating yellow pixels
saveas(hf4,'tree_rings_yellow.jpg')
%%%%
close all;clear all;clc
A20=imread('tree_rings_yellow.jpg');
hf1=figure(1);imshow(A20);ax1=hf1.CurrentAxes
% 008

.
.
A13=A20(:,:,1)-A20(:,:,3); % A23=A20(:,:,2)-A20(:,:,3);
[x13,y13]=find(A13>30);
% figure(2);imshow(A)
hold(ax1,'all');figure(2);h1=plot(ax1,y13,x13,'r.')
% 008
% ax1.DataAspectRatio=[9 9 1]
% axis(ax1,[791 1352 732 1201])
axis(ax1,[325 684 349 686])
the previous was marking ring pixels red, just to make sure marking the right pixels
9.-
solving the too short peaks, we need tall peaks against everything else for such purpose let's binarize
% BW better contrast
B=zeros(size(A20(:,:,1)));
for k=1:1:numel(x13)
B(x13(k),y13(k))=1;
end
hf2=figure(2);imshow(B);
ax2=hf2.CurrentAxes
% axis(ax2,[791 1352 732 1201])
axis(ax2,[325 684 349 686])
% 009
10.-
Now let's use flexible cross section, let's zig-zag, no need to count rings while pulling the cross section line,
but let's make sure that each straight section of cross section clearly gets one or more tree ring and if not just for clarity, that new sections start in between cross sections
p2=ginputRed
p2=floor(p2)
n=[p2(1,1) p2(1,2)];
for k=1:1:size(p2,1)-1
nx_section=floor(linspace(p2(k,1),p2(k+1,1),max(abs(p2(k,1)-p2(k+1,1)),abs(p2(k,2)-p2(k+1,2)))));
ny_section=floor(linspace(p2(k,2),p2(k+1,2),max(abs(p2(k,1)-p2(k+1,1)),abs(p2(k,2)-p2(k+1,2)))));
n=[n;nx_section' ny_section'];
end
n(1,:)=[];
hold(ax2,'all');
plot(ax2,p2(:,1),p2:,2),'r-','LineWidth',4);
plot(ax2,[p2(1,1) p2(end,1)],[p2(1,2) p2(end,2)],'ro','LineWidth',4);
% 010
variable peaks of interest amplitude solved, now all rings are 1s, and all space between rings are 0s
L=[];
for s=1:1:size(n,1)
L=[L B(n(s,2),n(s,1))];
end
mind the gap attempting the reading loop with B(n(s,1),n(s,2)) a result that looks ok is reached but neither the amount of rings nor the initial values of the cross section are correct.
figure(3);plot(L','r','LineWidth',3);grid on
% 011
.
counting peaks
.
[pks,locs]=findpeaks(L)
pks =
Columns 1 through 9
1 1 1 1 1 1 1 1 1
Columns 10 through 17
1 1 1 1 1 1 1 1
locs =
Columns 1 through 9
60 118 165 210 260 297 319 338 364
Columns 10 through 17
375 382 397 411 421 434 442 453
.
And the result is:
.
amount_rings=numel(pks)
=
17
.
Shivu
if you find this answer useful would you please be so kind to consider marking my answer as Accepted Answer?
To any other reader, if you find this answer useful please consider clicking on the thumbs-up vote link
thanks in advance for time and attention
John BG
.