I am creating gaussian pyramid in MATLAB 2010b. I want to show images like same patterned mentioned here.
I tried to use imresize, truesize but getting all images in same size. Could anybody please help me on this issue?
You can use "imshow with True Size for multiple images" FEX file to answer your question...
EDIT : The code below will produce the subplot at the bottom right part of the figure:
clear imagesCellArray
mand = imread('mandelbrot_set.jpg'); % read image
dim = 3;
[imagesCellArray{1:dim,1:dim}] = deal(mand); % create smaller images by imresize
for iRow = 1:dim
for iCol = 1:dim
imagesCellArray{iRow,iCol} = imresize(imagesCellArray{iRow,iCol},1/(1.5*(iCol*iRow)));
end
end
% plot with imshowTruesize - true aspect ratio is preserved
margins = [25 25];
Handles = imshowTruesize(imagesCellArray,margins);
for iRow = 1:dim
for iCol = 1:dim
axis(Handles.hSubplot(iRow,iCol),'on')
end
end
Related
I have an RGB image obtained from saving the imagesc function as shown below. how to refine/smoothen the edges present in the image.
It consists of sharper edges, where I need to smoothen them. Im not able to find a solution for performing this for an RGB image. Instead of the staircase effect seen in the image I'd like to even out the edges. Please help thanks in advance.
maybe imresize will help you:
% here im just generating an image similar to yours
A = zeros(20);
for ii = -2:2
A = A + (ii + 3)*diag(ones(20-abs(ii),1),ii);
end
A([1:5 16:20],:) = 0;A(:,[1:5 16:20]) = 0;
subplot(121);
imagesc(A);
title('original')
% resizing image with bi-linear interpolation
B = imresize(A,100,'bilinear');
subplot(122);
imagesc(B);
title('resized')
EDIT
here I do resize + filtering + rounding:
% generates image
A = zeros(20);
for ii = -2:2
A = A + (ii + 3)*diag(ones(20-abs(ii),1),ii);
end
A([1:5 16:20],:) = 0;A(:,[1:5 16:20]) = 0;
subplot(121);
imagesc(A);
title('original')
% resizing
B = imresize(A,20,'nearest');
% filtering & rounding
C = ceil(imgaussfilt(B,8));
subplot(122);
imagesc(C);
title('resized')
solution
use imfilter and fspecial to perform a convolution of you image with gaussian.
I = imread('im.png');
H = fspecial('gaussian',5,5);
I2 = imfilter(I,H);
change 'blurlevel' parameter (which determines the gaussian kernel size) to make the image smoother or sharper.
result
If you are just looking for straighter edges, like an elevation map you can try contourf.
cmap = colormap();
[col,row] = meshgrid(1:size(img,2), 1:size(img,1));
v = linspace(min(img(:)),max(img(:)),size(cmap,1));
contourf(col,row,img,v,'edgecolor','none');
axis('ij');
This produces the following result using a test function that I generated.
I have this MATLab code to count the number of objects in the image. There are two objects in the image I am choosing (a car and a cyclist). However, the program is returning a wrong output saying there are 0 objects. Can someone find the error in the code? Thanks.
The logic behind the code is:
1. Take two input images are given, one without objects and one with objects.
2. Convert the input images from RGB to Gray scale.
3. Compare the two images and find the difference.
4. Convert the image obtained to binary.
5. In the image, only open the blobs whose area is greater than 4000.
6. Display the count and density.
clc;
MV = imread('car.png'); %To read image
MV1 = imread('backgnd.png');
A = double(rgb2gray(MV)); %convert to gray
B= double(rgb2gray(MV1)); %convert 2nd image to gray
[height, width] = size(A); %image size?
h1 = figure(1);
%Foreground Detection
thresh=11;
fr_diff = abs(A-B);
for j = 1:width
for k = 1:height
if (fr_diff(k,j)>thresh)
fg(k,j) = A(k,j);
else
fg(k,j) = 0;
end
end
end
subplot(2,2,1) , imagesc(MV), title ({'Orignal Frame'});
subplot(2,2,2) , imshow(mat2gray(A)), title ('converted Frame');
subplot(2,2,3) , imshow(mat2gray(B)), title ('BACKGND Frame ');
sd=imadjust(fg); % adjust the image intensity values to the color map
level=graythresh(sd);
m=imnoise(sd,'gaussian',0,0.025); % apply Gaussian noise
k=wiener2(m,[5,5]); %filtering using Weiner filter
bw=im2bw(k,level);
bw2=imfill(bw,'holes');
bw3 = bwareaopen(bw2,5000);
labeled = bwlabel(bw3,8);
cc=bwconncomp(bw3);
Densityoftraffic = cc.NumObjects/(size(bw3,1)*size(bw3,2));
blobMeasurements = regionprops(labeled,'all');
numberofcars = size(blobMeasurements, 1);
subplot(2,2,4) , imagesc(labeled), title ({'Foreground'});
hold off;
disp(numberofcars); % display number of cars
disp(Densityoftraffic); %display number of vehicles
An empty image(of a road) with no objects(vehicles) in it
An image of the same road but with 2 objects(car and cyclist) in it
Try This it will help you in an optimize manner
clc
clear all
close all
im1 = imread('image1.png');
im2 = imread('image2.png');
gray1 = double(rgb2gray(im1));
gray2 = double(rgb2gray(im2));
absDif = mat2gray(abs(gray1 - gray2));
figure,imshow(absDif,[])
absDfbw = im2bw(absDif,0.9*graythresh(absDif));
figure,imshow(absDfbw,[])
absDfbw = bwareaopen(absDfbw,25);
absDfbw = imclose(absDfbw,strel('disk',5));
figure,imshow(absDfbw,[])
Results are:
Thank You
I was trying to binarize some images. In some images I get the pattern as it is but in some images I lose some of the pattern. I am using greythresh for binarizing. Is there any other method to improve the output.
I = imread('image.jpg');
I = rgb2gray(I);
I = uint8(255*mat2gray(I));
figure,imshow(I);
I=imresize(I,[128 128]);
figure,imshow(I);
I = medfilt2(I,[5 5]);
I1 = medfilt2(I,[5 5]);
I = adapthisteq(I1,'clipLimit',0.4,'Distribution','rayleigh');
figure,imshow(I);
level = graythresh(I);
BW = im2bw(I, level);
figure,imshow(BW);
input
output
Getting a unique threshold for the whole image seems to be bad in your case. You should try to perform adaptive local thresholding to better adapt to smooth image intensity variations.
You can find a matlab example here
Using MATLAB, I am trying to convert a randomly sized image into four equal blocks. I am working with "for" loops to create blocks. The problem I am facing is that these blocks are being converted into gray scale whereas I want the blocks to retain their original form i.e. RGB channel. Here is the code I am using:
clear all;
img1 = imread('ABC.png');
[rs, cols, colorchan] = size(img1);
rnew = int32(rs/2);
cnew = int32(cols/2);
for i = 1:4
for j = 1:4
imgij = img1((i-1)*rnew+1:i*rnew, (j-1)*cnew+1:j*cnew);
figure();
imshow(imgij);
%do some other stuff here%
end
end
I am new to MATLAB and that's the best I could do myself. Can somebody please tell me how to retain the original form of every block of the parent image? Any help will be highly appreciated.
You have considered only the width and height of the image. But actually for a colour image, colour is the 3rd dimension in Matlab. Try the following code.
img = imread('onion.png');
figure; imshow(img);
w = size(img,2); % width of the original image
h = size(img,1); % height of the original image
wm = floor(w/2); % middle of the width
hm = floor(h/2); % middle of the height
figure;
imgtl = img(1:hm,1:wm,:); % top left image
subplot(2,2,1); imshow(imgtl);
imgtr = img(1:hm,wm+1:w,:); % top right image
subplot(2,2,2); imshow(imgtr);
imgbl = img(hm+1:h,1:wm,:); % bottom left image
subplot(2,2,3); imshow(imgbl);
imgbr = img(hm+1:h,wm+1:w,:); % bottom right image
subplot(2,2,4); imshow(imgbr);
Original image:
Partitioned image:
I am doing vlfeat in Matlab and I am following this question here.
These below are my simple testing images:
Left Image:
Right Image:
I did a simple test with 2 simple images here (the right image is just rotated version of the left), and I got the result accordingly:
It works, but I have one more requirement, which is to match the SIFT points of the two images and show them, like this:
I do understand that vl_ubcmatch returns 2 arrays of matched indices, and it is not a problem to map them for which point goes to which point on two images. However, I am currently stuck in matlab's procedure. I found this. But that only works if the subplot stays that way. When you add an image into the subplot, the size changes and the normalization failed.
Here is my code: (im and im2 are images. f, d and f2, d2 are frames and descriptors from vl_sift function from 2 images respectively)
[matches score] = vl_ubcmatch(d,d2,threshold);%threshold originally is 1.5
if (mode >= 2)%verbose 2
subplot(211);
imshow(uint8(im));
hold on;
plot(f(1,matches(1,:)),f(2,matches(1,:)),'b*');
subplot(212);
imshow(uint8(im2));
hold on;
plot(f2(1,matches(2,:)),f2(2,matches(2,:)),'g*');
end
if (mode >= 3)%verbose 3
[xa1 ya1] = ds2nfu( f(1,matches(1,:)), f(2,matches(1,:)));
[xa2 ya2] = ds2nfu( f2(1,matches(2,:)), f2(2,matches(2,:)));
for k=1:numel(matches(1,:))
xxa1 = xa1(1, k);
yya1 = ya1(1, k);
xxa2 = xa2(1, k);
yya2 = ya2(1, k);
annotation('line',[xxa1 xxa2],[yya1 yya2],'color','r');
end
end
The code above yields this:
I think subplot isn't a good way to go for something like this. Is there a better method for this in Matlab? If possible, I want something like an empty panel that I can draw my image, draw lines freely and zoom freely, just like drawing 2D games in OpenGL style.
From zplesivcak's suggestion, yes, it is possible, and not that problematic after all. Here is the code:
% After we have applied vl_sift with 2 images, we will get frames f,f2,
% and descriptor d,d2 of the images. After that, we can apply it into
% vl_ubcmatch to perform feature matching:
[matches score] = vl_ubcmatch(d,d2,threshold); %threshold originally is 1.5
% check for sizes and take longest width and longest height into
% account
if (size(im,1) > size(im2,1))
longestWidth = size(im,1);
else
longestWidth = size(im2,1);
end
if (size(im,2) > size(im2,2))
longestHeight = size(im,2);
else
longestHeight = size(im2,2);
end
% create new matrices with longest width and longest height
newim = uint8(zeros(longestWidth, longestHeight, 3)); %3 cuz image is RGB
newim2 = uint8(zeros(longestWidth, longestHeight, 3));
% transfer both images to the new matrices respectively.
newim(1:size(im,1), 1:size(im,2), 1:3) = im;
newim2(1:size(im2,1), 1:size(im2,2), 1:3) = im2;
% with the same proportion and dimension, we can now show both
% images. Parts that are not used in the matrices will be black.
imshow([newim newim2]);
hold on;
X = zeros(2,1);
Y = zeros(2,1);
% draw line from the matched point in one image to the respective matched point in another image.
for k=1:numel(matches(1,:))
X(1) = f(1, matches(1, k));
Y(1) = f(2, matches(1, k));
X(2) = f2(1, matches(2, k)) + longestHeight; % for placing matched point of 2nd image correctly.
Y(2) = f2(2, matches(2, k));
line(X,Y);
end
Here is the test case:
By modifying the canvas width and height of one of the images from the question, we see that the algorithm above will take care of that and display the image accordingly. Unused area will be black. Furthermore, we see that the algorithm can match the features of two images respectively.
EDIT:
Alternatively, suggested by Maurits, for cleaner and better implementation, check out Lowe SIFT matlab wrappers.
If you have Matlab Computer Vision Library installed on your disc already, you can simply use
M1 = [f(1, match(1, :)); f(2, match(1, :)); ones(1, length(match))];
M2 = [f2(1, match(2, :)); f2(2, match(2, :)); ones(1, length(match))];
showMatchedFeatures(im,im2,[M1(1:2, :)]',[M2(1:2, :)]','montage','PlotOptions',{'ro','g+','b-'} );