edge detection via wavelet transform(dwt2) - matlab

I want to detect edges of an image via dwt2. In fact I am going to simulate this article.
The first step of edge detection is based on replacing of all approximation coefficients with zeros. But when I replace the approximation coefficients with zero, the edges aren't similar to results seen in the article.
Here is my code:
clc;
clear all,close all
img=imread('2.png');
img=img(:,:,1);
imshow(img);
L = medfilt2(img,[3 3]);
L=im2double(L);
[A,H,V,D]=dwt2(L,'haar');
A=zeros(size(A));
Q1 = idwt2(A,H,V,D,'haar');
figure;
subplot(1,2,1);
imshow(img);
subplot(1,2,2);
imshow(Q1);`
enter code here
clc;
clear all,close all
img=imread('2.png');
img=rgb2gray(img);
L = medfilt2(img,[3 3]);
t=graythresh(L);
b=im2bw(L,t);
[A,H,V,D]=dwt2(b,'haar');
A1=zeros(size(A));
Q1 = idwt2(A1,H,V,D,'haar');
figure;
subplot(1,2,1);
imshow(img);
subplot(1,2,2);
imshow(Q1);

Related

Octave/Matlab High Boost filtering

I have to use a Gaussian lowpass filter for the blurring step and then I have to improve the sharpness of the result using high-boost filtering.
Here is what I have so far:
I=imread('blurry-moon.tif');
A = fft2(double(I));
Ashift=fftshift(A);
[m n]=size(A);
R=10;
X=0:n-1;
Y=0:m-1;
[X Y]=meshgrid(X,Y);
Cx=0.5*n;
Cy=0.5*m;
LoF=exp(-((X-Cx).^2+(Y-Cy).^2)./(2*R).^2);
Gauss=Ashift.*LoF;
GaussShift=ifftshift(Gauss);
InverseGauss=ifft2(GaussShift);
%High boost
f = double(InverseGauss);
[m n]=size(f);
J0 = f;
for i=3:m-2
for j=3:n-2
J0(i,j) = (-8*f(i,j))+(1*f(i-1,j))+(1*f(i+1,j))+(1*f(i,j-1))+(1*f(i,j+1))...
+(1*f(i-1,j-1))+(1*f(i+1,j+1))+(1*f(i-1,j+1))+(1*f(i+1,j-1));
end
end
%----visualizing the results----------------------------------------------
figure(1)
imshow(I);colormap gray
title('original image','fontsize',14)
figure(2)
imshow(abs(Ashift),[-12 300000]), colormap gray
title('fft of original image','fontsize',14)
figure(3)
imshow(abs(InverseGauss),[12 290]), colormap gray
title('low pass filtered image','fontsize',14)
figure(4)
imshow(abs(J0),[12 290]), colormap gray
title('final image','fontsize',14)
I think I do something wrong in the high boost. But I think I am doing the gaussian filter right?
Can someone help out with the high boost filter?
Best regards!
img = imread('moon.tif');
% create gaussian filter
h = fspecial('gaussian',5,2.5);
% blur the image
blurred_img = imfilter(img,h);
% subtract blurred image from original
diff_img = img - blurred_img;
% add difference to the original image
highboost_img = img + 3*diff_img;
subplot 221
imshow(img,[]);
title('Original Image')
subplot 222
imshow(blurred_img,[]);
title('Blurred Image')
subplot 223
imshow(diff_img,[]);
title('Difference Image')
subplot 224
imshow(highboost_img,[]);
title('HighBoosted Image')

How to find peaks in an image using matlab?

I am trying to outline all peaks in an image. The brightest lines are the peaks. I am using Matlab. This is what I have so far....
Any help will be greatly appreciated. Here is the image.
a = imread('duneLiDARs.png');
%b = imregionalmax(a);
%a = rgb2gray(a);
c = edge(a,'Sobel');
b = edge(a,'log',.0006);
d = edge(a,'log');
c= imfuse(a,d);
d= d-b;
subplot(2,2,1), imshow(a)
subplot(2,2,2), imshow(b)
subplot(2,2,3), imshow(c)
subplot(2,2,4), imshow(d)
%imshow(b);
%c = imadd(a,b);
%imshow(b);
you need to define what do you consider as peaks - what is the desired output for your image.
however, there are some general 2D peaks finding function, the following code uses FEX's extrema2:
% load image and remove extreme noise
im = medfilt2( im2double(imread('dune.png')));
% find peaks using extrema2
[XMAX,IMAX,XMIN,IMIN] = extrema2(im);
% eliminate peaks under minimum threshold
underThresh = XMAX < 0.15;
IMAX(underThresh) = [];
XMAX(underThresh) = [];
% plotting
subplot(121);
surf(im,'EdgeColor','none');
hold on;
[y,x] = ind2sub(size(im),IMAX);
scatter3(x,y,XMAX,'r','filled');
axis square
subplot(122);
imshow(im,[]);
hold on;
scatter(x,y,'r','filled');

MATLAB: Apply a low-pass filter to an image

I am trying to implement a simple low-pass filter using "ones" function as a filter and "conv2" to compute the convolution of both matrices (the original image and the filter), which is the filtered image I want to get, but the result of imshow(filteredImage) is just an empty white image instead of a filtered image.
I have checked the matrice of the filtered image, it is a 256x256 double, but I don't know the reason why it isn't displayed properly.
I = imread('cameraman.tif');
filteredImage = conv2(double(I), double(ones(3,3)), 'same');
figure; subplot(1,2,1); imshow(filteredImage);title('filtered');
subplot(1,2,2); imshow(I); title('original');
EDIT:
I have also tried converting it to double first before calculating the convolution as it was exceeding 1, but it didn't give a low-pass filter effect, but the image's contrast got increased instead.
I = imread('cameraman.tif');
I1 = im2double(I);
filteredImage = conv2(I1, ones(2,2), 'same');
figure; subplot(1,2,1); imshow(filteredImage);title('filtered');
subplot(1,2,2); imshow(I1); title('original');
The following solution has fixed the range issue, the other solutions that were given were about a specific type of low-pass filters which is an averaging filte :
Img1 = imread('cameraman.tif');
Im=im2double(Img1);
filteredImage = conv2(Im, ones(3,3));
figure; subplot(1,2,1); imshow(filteredImage, []);title('filtered');
subplot(1,2,2); imshow(Im); title('original');
Instead of dividing by the kernel, I've used imshow(filteredImage, []).

How can I count no. of holes in an image and measure their diameter using matlab morphological operators?

So I have a graylevel image that demonstrates an electronic circuit card and I'm supposed to inspect the number of holes and the diameter of the holes, and I'm also allowed to use morphology operators in Matlab. The image is as follows:
I could wrote some codes that can count number of holes, but I don't know how to measure their diameters!
clear; close all; clc; warning off
im = imread('input\pcb.jpg');
im1 = im2bw(im,0);
% im1 = ~im2bw(im,0);
figure; imshow(im1);
strel1 = strel('disk',2);
im2 = imclose(im1,strel1);
figure; imshow(im2);
im3 = imfill(im2,'holes');
figure; imshow(im3);
im4 = im3 & ~im1;
figure; imshow(im4);
strel2 = strel('disk',3);
im5 = imopen(im4,strel2);
figure; imshow(im5);
[~,numCC] = bwlabel(im5);
fprintf('Number of holes equals:\t%d\n',numCC);
I appreciate any comments in advance!
Finally I just wrote some code, and it seems that it's working somehow perfect!
Actually the number of holes are counted as 4 and their diameters are not precise ones but they're approximated using built-in MATLAB functions. The thing is that one of the holes is not separated distinctly! and it makes the results estimated ...
clear; close all; clc; warning off
im = imread('input\pcb.jpg');
level = graythresh(im);
imBin = im2bw(im,level);
figure(1); imshow(imBin); title('Binarized Original Image');
imBinInv = ~imBin;
figure(2); imshow(imBinInv); title('Inverted Binarized Original Image');
imInvHolSep = imdilate(imerode(imBinInv,strel('disk',21)),strel('disk',23));
figure(3); imshow(imInvHolSep); title('Inverted Holes Separated');
imInHolSepBound = imInvHolSep & ~imerode(imInvHolSep,strel('disk',2));
figure(4); imshow(imInHolSepBound); title('Inverted Holes Boundaries');
imInvHolSepFill = imfill(imInHolSepBound,'holes');
figure(5); imshow(imInvHolSepFill); title('Inverted Holes Filled After Setting Boundaries');
imInvHolSepDist = imerode(imInvHolSepFill,strel('disk',1));
figure(6); imshow(imInvHolSepDist); title('Inverted Holes Eroded Just For The Case of Indistinct Hole');
imInvHolSepMinus = imInvHolSepDist & ~imBin;
figure(7); imshow(imInvHolSepMinus); title('Inverted Holes Minus The Inverted Binarized Image');
imInvHolSepSmooth = imdilate(imInvHolSepMinus,strel('disk',2));
figure(8); imshow(imInvHolSepSmooth); title('Final Approximated Inverted Holes Smoothed');
[~,numCC] = bwlabel(imInvHolSepSmooth);
fprintf('Number of holes equals:\t%d\n',numCC);
stats = regionprops(imInvHolSepSmooth);
centroid = zeros(length(stats),2);
area = zeros(length(stats),1);
for c1 = 1:length(stats)
centroid(c1,:) = stats(c1).Centroid;
area(c1) = stats(c1).Area;
fprintf('Diameter of the hole with centroid coordinates [%.2f, %.2f] is:\t%.2f\n',centroid(c1,1),centroid(c1,2),sqrt(area(c1)/pi));
end

Drawing the major and minor axis of an elliptical object in MATLAB

This program currently inputs an image of a coin, thresholds it, binarizes it, and finds the major and minor axis lengths of the segmented elliptical using the regionprops function. How do I output a subplot where I draw the axes used to calculate the 'MajorAxisLength' and 'MinorAxisLength' over the original image?
I have appended my code for your perusal.
% Read in the image.
folder = 'C:\Documents and Settings\user\My Documents\MATLAB\Work';
baseFileName = 'coin2.jpg';
fullFileName = fullfile(folder, baseFileName);
fullFileName = fullfile(folder, baseFileName);
if ~exist(fullFileName, 'file')
fullFileName = baseFileName; % No path this time.
if ~exist(fullFileName, 'file')
%Alert user.
errorMessage = sprintf('Error: %s does not exist.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
rgbImage = imread(fullFileName);
% Get the dimensions of the image. numberOfColorBands should be = 3.
[rows columns numberOfColorBands] = size(rgbImage);
% Display the original color image.
subplot(2, 3, 1);
imshow(rgbImage, []);
title('Original color Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'Position', get(0,'Screensize'));
% Extract the individual red color channel.
redChannel = rgbImage(:, :, 1);
% Display the red channel image.
subplot(2, 3, 2);
imshow(redChannel, []);
title('Red Channel Image', 'FontSize', fontSize);
% Binarize it
binaryImage = redChannel < 100;
% Display the image.
subplot(2, 3, 3);
imshow(binaryImage, []);
title('Thresholded Image', 'FontSize', fontSize);
binaryImage = imfill(binaryImage, 'holes');
labeledImage = bwlabel(binaryImage);
area_measurements = regionprops(labeledImage,'Area');
allAreas = [area_measurements.Area];
biggestBlobIndex = find(allAreas == max(allAreas));
keeperBlobsImage = ismember(labeledImage, biggestBlobIndex);
measurements = regionprops(keeperBlobsImage,'MajorAxisLength','MinorAxisLength')
% Display the original color image with outline.
subplot(2, 3, 4);
imshow(rgbImage);
hold on;
title('Original Color Image with Outline', 'FontSize',fontSize);
boundaries = bwboundaries(keeperBlobsImage);
blobBoundary = boundaries{1};
plot(blobBoundary(:,2), blobBoundary(:,1), 'g-', 'LineWidth', 1);
hold off;
I had the same task as you for some project I did 2 years ago. I've modified the code I used then for you below. It involved calculating the covariance matrix for the datapoints and finding their eigenvalues/eigenvectors. Note here that because of circular symmetry, the minor and major axis will be somewhat "random". Also note that I have made the image binary in a very naïve way to keep the code simple.
% Load data and make bw
clear all;close all; clc;
set(0,'Defaultfigurewindowstyle','docked')
I = imread('american_eagle_gold_coin.jpg');
Ibw = im2bw(I,0.95);
Ibw = not(Ibw);
figure(1);clf
imagesc(Ibw);colormap(gray)
%% Calculate axis and draw
[M N] = size(Ibw);
[X Y] = meshgrid(1:N,1:M);
%Mass and mass center
m = sum(sum(Ibw));
x0 = sum(sum(Ibw.*X))/m;
y0 = sum(sum(Ibw.*Y))/m;
%Covariance matrix elements
Mxx = sum(sum((X-x0).^2.*Ibw))/m;
Myy = sum(sum((Y-y0).^2.*Ibw))/m;
Mxy = sum(sum((Y-y0).*(X-x0).*Ibw))/m;
MM = [Mxx Mxy; Mxy Myy];
[U S V] = svd(MM);
W = V(:,1)/sign(V(1,1)); %Extremal directions (normalized to have first coordinate positive)
H = V(:,2);
W = 2*sqrt(S(1,1))*W; %Scaling of extremal directions to give ellipsis half axis
H = 2*sqrt(S(2,2))*H;
figure(1)
hold on
plot(x0,y0,'r*');
quiver(x0,y0,W(1),H(1),'r')
quiver(x0,y0,W(2),H(2),'r')
hold off
Look at the documentation for the Orientation attribute that regionprops() can return to you.
This gives the angle between the positive x-axis and the major axis of the ellipse. You should be able to derive the equation for the major axis line in terms of that angle, and then just make a grid of x-axis points, and compute the major axis line's value for all the points in your grid, then just plot it like you would plot any other curve in MATLAB.
To do the same for the minor axis, just note that it will be 90 degrees further counter-clockwise from the major axis, then repeat the step above.
Usually one does it with computing eigenvectors, as explained in the Wikipedia article Image moment under 'examples'. That would be the correct way.
But I wonder, if you know the centroid and the boundingbox from MATLAB, then the endpoint of the major axis must be in the upper left or upper right corner. So checking (apart from noise) these two corners, if there are pixel, would give you the major axis. The minor axis then is just orthogonal to it with respect to the centroid.
Sorry for not having MATLAB code ready.
The reasoning is not that wrong, but not so good either, using the orientation as written above is better ;)