Morphological closing by reconstructions in Matlab - matlab

Could you please advice how can I implement morphological closing by reconstruction in Matlab?
As i know imreconstruct command can be used to implement opening by reconstruction (below my code for Opening by reconstruction).
img = rgb2gray(imread("input.jpg"));
img = imcomplement(img);
se=strel("square", 40);
marker= imerode(img,se);
mask=img;
opn_recon=imreconstruct(marker,mask);
Below is the code I wrote for Closing Reconstruction:
%Closing by reconstruction
img = rgb2gray(imread("input.jpg"));
img = imcomplement(img);
se=strel("square", 40);
marker= imdilate(img,se);
tmp=0;
while 1
marker_loop = marker;
geodesic=max(marker_loop,img);
recon=imerode(geodesic,se);
if isequal(recon,tmp)==1
break
end
tmp = recon;
marker = imdilate(marker_loop,se);
end
But code does not work properly. Could you please advice whats my mistake, so i can fix it?

imreconstruct applies an inf-reconstruction, which can be interpreted as the repeated dilation conditioned by a second image (mask). Because it's a dilation, it can be applied after a structural erosion to form an opening (opening by reconstruction).
To form a closing by reconstruction, we need to apply a dilation followed by a sup-reconstruction. The sup-reconstruction is the dual of the inf-reconstruction, and can therefore be interpreted as the repeated erosion conditioned by a second image. Being the dual, we can implement the sup-reconstruction in terms of the ind-reconstruction by inverting the image, applying the operation, and then inverting the result:
out = imcomplement(imreconstruct(imcomplement(marker), imcomplement(mask)));
Thus, the closing by reconstruction is:
img = imread('cameraman.tif');
se = strel('square', 40);
marker = imdilate(img,se);
mask = img;
cls_recon = imcomplement(imreconstruct(imcomplement(marker), imcomplement(mask)));

Related

Why my segmentation using HSV space isn't giving me a good result?

I am attending a class on image processing with Matlab and I found a problem on the internet and I tried to solve it but it is hard, because I am new to this subject.
The problem has to be solved with Matlab and it is new for me as well.
Problem:
'Think of RGB and HSV spaces as 3-dimensional spaces. Define a
neighborhood distance (we can use ecludien distance) and set to 0 all
the pixels whose value in RGB or HSV space is far (in the sense of
this distance) from your reference value. See if you can easily
achieve the same type of segmentation in both cases. Try for example
to segment only the helmets of the warriors of the image
bilibinWar.jpg.'
I tried to code it but i don't know if the result is good.
%%
% 4) 8 - Segmentatiion dans l’’espace HSV et RVB..
clear all; close all;
ImagebilibinWar = imread("bilibinWar.jpg");
[lin, col, pla] = size(ImagebilibinWar);
figure(1);imshow(ImagebilibinWar);
Image_bilibinWar_HSV= rgb2hsv(ImagebilibinWar);
[lo,co] = ginput(1);
lo = round(lo);
co = round(co);
RIOH = Image_bilibinWar_HSV(lo,co,1);
%%
% Im going to use this first section so ican isolate the helmets inside a circle ARROUND THE HELMETS and get rid of REST background Circle_Image_bilibinWar_HSV = Image_bilibinWar_HSV;
for i= 1:lin
for j = 1:col
d(i,j) = ((i-lo)^2 + (j-co)^2)^0.5;
if d(i,j,:) > 90
Circle_Image_bilibinWar_HSV(i,j,:) = 0;
end
end
end
Circle_Image_bilibinWar_RGB = hsv2rgb(Circle_Image_bilibinWar_HSV);
figure(2);imshow(Circle_Image_bilibinWar_RGB); % i have isolated the circle
%% here im going to isolate the helmets inside the circle
figure(3); imshow(Circle_Image_bilibinWar_HSV); % as u can see here i will try to isolate the helmets from the rest
New_Circle_Image_bilibinWar_HSV = Circle_Image_bilibinWar_HSV % assinging a new image so as i can work on it seperatly;
valueH = New_Circle_Image_bilibinWar_HSV(lo,co,1);
for i=1:lin
for j=1:col
if (New_Circle_Image_bilibinWar_HSV(i,j,1) > valueH + 0.19)
New_Circle_Image_bilibinWar_HSV(i,j,:) = 0;
end
end
end
Circle_Image_bilibinWar_HSV = Circle_Image_bilibinWar_HSV - New_Circle_Image_bilibinWar_HSV;
NEW_Image_bilibinWar_RGB = hsv2rgb(Circle_Image_bilibinWar_HSV);
figure(4); subplot(1,2,1);imshow(ImagebilibinWar);
subplot(1,2,2);imshow(NEW_Image_bilibinWar_RGB);
So can some one help me with it? i don't know if its good and if not how can i make it good ?
I don't think there is anything wrong with your code. The answer is that segmenting using euclidean distance in colors simply does not work for RGB or HSV spaces. The entire purpose of the L*a*b color space was indeed this, creating a color space where similar colors would have the little euclidean distance.
Here a less cluttered version of it:
clear all; close all;
ImagebilibinWar = imread("https://i.stack.imgur.com/wnBDu.jpg");
[lin, col, pla] = size(ImagebilibinWar);
figure;imshow(ImagebilibinWar);
ImagebilibinWarHSV= rgb2hsv(ImagebilibinWar);
[lo,co] = ginput(1);
lo = round(lo);
co = round(co);
RIOH = ImagebilibinWarHSV(lo,co,1);
RIOS = ImagebilibinWarHSV(lo,co,2);
RIOV = ImagebilibinWarHSV(lo,co,3);
%reference value that i have to choose
for a=0:0.05:1
d = ((ImagebilibinWarHSV(:,:,1)-RIOH).^2 + (ImagebilibinWarHSV(:,:,2)-RIOS).^2+(ImagebilibinWarHSV(:,:,3)-RIOV).^2).^0.5;
ImagebilibinWarRGB = hsv2rgb(ImagebilibinWarHSV.*double(d<a));
figure;imshow(ImagebilibinWarRGB);
end

DIPimage measure missing argument

I am trying to use DIPimage to get some measurements of each object in an image and I get this error:
Error using dip_measure
DIPlib Error in function dip_Measure.
DIPlib Error in function dip_ImageCheck: Data type not supported
Error in measure (line 209)
data = dip_measure(object_in,gray_in,measurementID,objectIDs,connectivity);
Error in Untitled (line 13)
msr = measure(b, [], ({'size', 'perimeter','podczeckShapes'}))
How can I solve it?
Code:
Image = rgb2gray(imread('pillsetc.png'));
BW = imbinarize(Image);
BW = imfill(BW,'holes');
imshow(BW);
[B,L] = bwboundaries(BW,'noholes');
k = 1;
b = B{k};
y = b(:,2);
x = b(:,1);
msr(k) = measure(BW, [], ({'size', 'perimeter','podczeckShapes'}))
sz = msr.size;
podczeckShapes = podczeckShapes;
One problem with your code is the call to imfill. Because the image has bright values all around the image, it is considered that there's a large object with a hole, and your actual objects are inside this hole. imfill fills the hole, leaving the whole image white.
Instead, I suggest the following code to remove the frame:
Image = rgb2gray(imread('https://i.stack.imgur.com/fmqAF.jpg'));
BW = imbinarize(Image);
BW = BW - bpropagation(false(size(BW)), BW);
Because we used a filter in DIPimage, the BW variable now contains a dip_image object, not a normal MATLAB array. dip_array(BW) extracts the normal MATLAB array that is inside. The dip_image object behaves differently from a MATLAB array. For example, you can display it to an interactive figure window by just typing its name:
BW
Next, we apply labeling so that we know which object ID in the measurement data corresponds to which object:
lab = label(BW);
dipshow(lab,'labels')
Now we can apply the measurement function. If we use BW as input, label will be called on it. Since we already have that result, let's use it directly:
msr = measure(lab, [], {'size', 'perimeter','podczeckShapes'});
Let's examine results for object ID 8, which is the large square:
sz = msr(8).size
square = msr(8).podczeckShapes(1)
triangle = msr(8).podczeckShapes(3)
There are other things you can do with the measurement structure, I suggest you read the documentation. For example, we can remove from it the measurement for the littlest objects, which to me look like noise:
msr = msr(msr.size>100); % remove measurement for noise

Image processing - Character count in dot printed text

I have to count the characters that is printed in a beverage tin[1]. So far i have done till removing noise and unwanted pixels and now my text is clear to read 2 but is there any way to count them properly. Ocr fails to detect this text. Or should i join these dots using some algorithm and continue with ocr function?
ROI of image
Here is the code which gave me the above picture.
clear all; close all;
a=imread('coke.jpg');
gray=rgb2gray(a);
thres=150;
lbw=double(gray>thres);
imwrite(lbw,'--\OCR\output.png');
a=imread('output.png');
c=imresize(a,.5);
b = im2bw(c, .9);
b=imcomplement(b);
imwrite(b,'compli.png');
You should definitely join the dots. The first thing I would try is the imclose function, which does morphological closing (dilation followed by erosion).
For example, you could try this:
im = imread('dotMatrix.png');
im2 = imclose(im, strel('line', 5, 90));
im3 = imclose(im2, strel('line', 5, 45));

Transmission of the image using BPSK

Input image needs to be modulated and transmitted and finally detected using BPSK.
M = 2; %Modulation order 2 for BPSK
randn('state',200); % initializing the randn() function
imdata = imread('lenna.pgm');
bdata = de2bi(imdata);
sizec = size(bdata,1); % height
sizer = size(bdata,2); % width
nbits = sizec*sizer; % number of bits in the image
msg = double(reshape(bdata,nbits,1));
The following code is meant to modulate the input image and display the demodulated output.The resultant output,when i run the code,I get a blank image.Need help in figuring out what I have missed or where I have gone wrong.
%modulate
txpsk = pskmod(msg,M);
%noise
phasenoise = randn(nbits,1)*0.015;
rxpsk = txpsk.*exp(2i*pi*phasenoise);
%demodulate
recovpsk = pskdemod(rxpsk,M);
reshape1rxpsk = reshape(recovpsk,sizec,sizer);
reshape2rxpsk = bi2de(reshape1rxpsk);
finalout= reshape(reshape2rxpsk,size(imdata,1),size(imdata,2));
imshow(finalout)
A PGM file consists of a sequence of one or more PGM images. Each image has a header structure, containing such information, as width, height e.t.c. After modulation you add a noise to your signal. Therefore, the demodulated signal may contain errors. If this errors corrupts header information of image - this may lead to blank image output. Try to comment lines
%phasenoise = randn(nbits,1)*0.015;
%rxpsk = txpsk.*exp(2i*pi*phasenoise);

Matlab Image Display

Below is a function I wrote in Matlab. The function works correctly but the output displays three different images of different outputs.
function Img = power_Law(Img)
temp = Img;
[a,b]=size(Img);
C=0.2;
omega=0.2;
for i=1:a
for j=1:b
img(i,j)=C*power(temp(i,j),omega);
end
end
imshow(img);
end
My Question is am I missing any conversions? Why wouldn't the output be a single Image.
Here is a link of the output.
https://www.dropbox.com/s/p6vuhzodk29qaul/image.png
You will notice that in Matlab and Octave operation performed for matrices are dramatically faster comparing to loops over their elements. Also loops will create a possibility to make a mistake.
Let say Img is of size 900x1200x3, then img will be of size 900x3600 because [a,b]=size(img) returns a = 900, b = 3600 as Img is three dimensional array.
Then proper code will look something like this, note it doesn't change dimensionality of img2
function img2 = power_law(img, C, omega)
img2 = C * power(img, omega);
imshow(img2);
end