I'm trying to compute the average of every pixel with just the left and right neighbors but at the end of my processing I get only a white image, I can't find where my error. Here's my code
imageIn = imread('Prueba.jpg');
imageIn = rgb2gray(imageIn);
imageOut = zeros(size(imageIn));
ny = size(imageIn, 1);
nx = size(imageIn, 2);
imshow(imageIn);
u = [];
v = [];
tic
for i = 1:ny
u = imageIn(i,:);
v = zeros(1, ny);
for k = 2:ny-1
v(k) = (uint32(u(k-1))+uint32(u(k))+uint32(u(k+1)))/3;
end
%Special cases first and last pixel
v(1) = (uint32(u(2))+uint32(u(1))+uint32(u(2)))/3;
v(ny) = (uint32(u(ny-1))+uint32(u(ny))+uint32(u(ny-1)))/3;
imageOut(i,:) = v;
end
toc
imshow(imageOut);
Any ideas?
Change the last line of your code to imagesc(imageOut) and you'll see that the image is not in fact white.
Your code is fine; the reason the image appears white using the imshow() function is because after applying your local average the range of pixel intensities is considerably smaller and the default scaling used by imshow() is insufficient to bring out the contrast of the image.
Read about the difference b/t imshow() and imagesc() and you'll see the confusion.
Why not just create a 2nd matrix which is a clone of the first, shift it over and then averate the two matrices?
imIn = imread('Prueba.jpg');
nx = size(d,1);
ny = size(d,2);
% Create temporary matrices padded with nan
tmp1 = [nan(ny,2), d];
tmp2 = [d, nan(ny,2)];
imOut = tmp1;
imOut(:,:,2) = tmp2;
% use nanmean so the mean is just the value of the 1 column
imOut = nanmean(imOut,3);
out = imOut(2:end-1,:);
Try to use this
imageIn = imread('Prueba.jpg');
imageIn = rgb2gray(imageIn);
imageOut = zeros(size(imageIn));
ny = size(imageIn, 1);
nx = size(imageIn, 2);
imshow(imageIn);
u = [];
v = [];
tic
for i = 1:ny
u = imageIn(i,:);
v = zeros(1, ny);
for k = 2:ny-1
v(k) = (uint32(u(k-1))+uint32(u(k))+uint32(u(k+1)))/3;
end
%Special cases first and last pixel
v(1) = (uint32(u(2))+uint32(u(1))+uint32(u(2)))/3;
v(ny) = (uint32(u(ny-1))+uint32(u(ny))+uint32(u(ny-1)))/3;
imageOut(i,:) = v;
end
toc
imshow(imageOut);
Related
I = imread('Sub1.png');
figure, imshow(I);
I = imcomplement(I);
I = double(I)/255;
I = adapthisteq(I,'clipLimit',0.0003,'Distribution','exponential');
k = 12;
beta = 2;
maxIter = 100;
for i=1:length(beta)
[seg,prob,mu,sigma,it(i)] = ICM(I, k, beta(i), maxIter,5);
pr(i) = prob(end);
hold on;
end
figure, imshow(seg,[]);
and ICM function is defined as
function [segmented_image,prob,mu,sigma,iter] = ICM(image, k, beta, max_iterations, neigh)
[width, height, bands] = size(image);
image = imstack2vectors(image);
segmented_image = init(image,k,1);
clear c;
iter = 0;
seg_old = segmented_image;
while(iter < max_iterations)
[mu, sigma] = stats(image, segmented_image, k);
E1 = energy1(image,mu,sigma,k);
E2 = energy2(segmented_image, beta, width, height, k);
E = E1 + E2;
[p2,~] = min(E2,[],2);
[p1,~] = min(E1,[],2);
[p,segmented_image] = min(E,[],2);
prob(iter+1) = sum(p);
%find mismatch with previous step
[c,~] = find(seg_old~=segmented_image);
mismatch = (numel(c)/numel(segmented_image))*100;
if mismatch<0.1
iter
break;
end
iter = iter + 1;
seg_old = segmented_image;
end
segmented_image = reshape(segmented_image,[width height]);
end
Output of my algorithm is a logical matrix (seg) of size 305-by-305. When I use
imshow(seg,[]);
I am able to display the image. It shows different component with varying gray value. But bwlabel returns 1. I want to display the connected components. I think bwlabel thresholds the image to 1. unique(seg) returns values 1 to 10 since number of classes used in k-means is 10. I used
[label n] = bwlabel(seg);
RGB = label2rgb(label);
figure, imshow(RGB);
I need all the ellipse-like structures which are in between the two squares close to the middle of the image. I don't know the number of classes present in it.
Input image:
Ground truth:
My output:
If you want to explode the label image to different connected components you need to use a loop to extract labels for each class and sum label images to get the out label image.
u = unique(seg(:));
out = zeros(size(seg));
num_objs = 0;
for k = 1: numel(u)
mask = seg==u(k);
[L,N] = bwlabel(mask);
L(mask) = L(mask) + num_objs;
out = out + L;
num_objs = num_objs + N ;
end
mp = jet(num_objs);
figure,imshow(out,mp)
Something like this is produced:
I have tried to do everything out of scratch. I wish it is of some help.
I have a treatment chain that get at first contours with parameters tuned on a trial-and-error basis, I confess. The last "image" is given at the bottom ; with it, you can easily select the connected components and do for example a reconstruction by markers using "imreconstruct" operator.
clear all;close all;
I = imread('C:\Users\jean-marie.becker\Desktop\imagesJPG10\spinalchord.jpg');
figure,imshow(I);
J = I(:,:,1);% select the blue channel because jpg image
J=double(J<50);% I haven't inverted the image
figure, imshow(J);
se = strel('disk',5);
J=J-imopen(J,se);
figure, imshow(J);
J=imopen(J,ones(1,15));% privilegizes long horizontal strokes
figure, imshow(J);
K=imdilate(J,ones(20,1),'same');
% connects verticaly not-to-far horizontal "segments"
figure, imshow(K);
I'm writing the code in Matlab to find interest point using DoG in the image.
Here is the main.m:
imTest1 = rgb2gray(imread('1.jpg'));
imTest1 = double(imTest1);
sigma = 0.6;
k = 5;
thresh = 3;
[x1,y1,r1] = DoG(k,sigma,thresh,imTest1);
%get the interest points and show it on the image with its scale
figure(1);
imshow(imTest1,[]), hold on, scatter(y1,x1,r1,'r');
And the function DoG is:
function [x,y,r] = DoG(k,sigma,thresh,imTest)
x = []; y = []; r = [];
%suppose 5 levels of gaussian blur
for i = 1:k
g{i} = fspecial('gaussian',size(imTest),i*sigma);
end
%so 4 levels of DoG
for i = 1:k-1
d{i} = imfilter(imTest,g{i+1}-g{i});
end
%compare the current pixel in the image to the surrounding pixels (26 points),if it is the maxima/minima, this pixel will be a interest point
for i = 2:k-2
for m = 2:size(imTest,1)-1
for n = 2:size(imTest,2)-1
id = 1;
compare = zeros(1,27);
for ii = i-1:i+1
for mm = m-1:m+1
for nn = n-1:n+1
compare(id) = d{ii}(mm,nn);
id = id+1;
end
end
end
compare_max = max(compare);
compare_min = min(compare);
if (compare_max == d{i}(m,n) || compare_min == d{i}(m,n))
if (compare_min < -thresh || compare_max > thresh)
x = [x;m];
y = [y;n];
r = [r;abs(d{i}(m,n))];
end
end
end
end
end
end
So there's a gaussian function and the sigma i set is 0.6. After running the code, I find the position is not correct and the scales looks almost the same for all interest points. I think my code should work but actually the result is not. Anybody know what's the problem?
i'm making image segmentation with self organizing map. the image segement by 3 cluster. Sample image is :
and i have type the matlab code like this bellow :
clear;
clc;
i=imread('DataSet/3.jpg');
I = imresize(i,0.5);
cform = makecform('srgb2lab');
lab_I = applycform(I,cform);
ab = double(lab_I(:,:,2:3));
nrows = size(ab,1);
ncols = size(ab,2);
ab = reshape(ab,nrows*ncols,2);
a = ab(:,1);
b = ab(:,2);
normA = (a-min(a(:))) ./ (max(a(:))-min(a(:)));
normB = (b-min(b(:))) ./ (max(b(:))-min(b(:)));
ab = [normA normB];
newnRows = size(ab,1);
newnCols = size(ab,2);
cluster = 3;
% Max number of iteration
N = 90;
% initial learning rate
eta = 0.3;
% exponential decay rate of the learning rate
etadecay = 0.2;
%random weight
w = rand(2,cluster);
%initial D
D = zeros(1,cluster);
% initial cluster index
clusterindex = zeros(newnRows,1);
% start
for t = 1:N
for data = 1 : newnRows
for c = 1 : cluster
D(c) = sqrt(((w(1,c)-ab(data,1))^2) + ((w(2,c)-ab(data,2))^2));
end
%find best macthing unit
[~, bmuindex] = min(D);
clusterindex(data)=bmuindex;
%update weight
oldW = w(:,bmuindex);
new = oldW + eta * (reshape(ab(data,:),2,1)-oldW);
w(:,bmuindex) = new;
end
% update learning rate
eta= etadecay * eta;
end
%Label Every Pixel in the Image Using the Results from KMEANS
pixel_labels = reshape(clusterindex,nrows,ncols);
%Create Images that Segment the I Image by Color.
segmented_images = cell(1,3);
rgb_label = repmat(pixel_labels,[1 1 3]);
for k = 1:cluster
color = I;
color(rgb_label ~= k) = 0;
segmented_images{k} = color;
end
figure,imshow(segmented_images{1}), title('objects in cluster 1');
figure,imshow(segmented_images{2}), title('objects in cluster 2');
figure,imshow(segmented_images{3}), title('objects in cluster 3');
and after runing the matlab code, there is no image segmentation result. Matlab show 3 figure, Figure 1 show the full image, figure 2 blank, figure 3 blank .
please anyone help me to revise my matlab code, is any wrong code or something?
new = oldW + eta * (reshape(ab(data,:),2,1)-oldW);
This line looks suspicious to me, why you are subtracting old weights here, i dont think this makes any sense there, just remove oldW from there and check your results again.
Thank You
I'm trying to implement the Prewitt Filter in Matlab. I know that Matlab has already this kind of filter but I need to code it myself. Below is my code, the only problem is that at the end of the filtering I get a bright image instead of seeing the edges.
I'm implementing the filter using the separability property of the Prewitt Filter. Any ideas? I will appreciate very much your help.
%% 3x3 Prewitt Filter
close all
imageIn = imread('images/Bikesgray.jpg');
imageGx = zeros(size(imageIn));
imageGy = zeros(size(imageIn));
imageOut = zeros(size(imageIn));
ny = size(imageIn, 1);
nx = size(imageIn, 2);
average = 3;
imshow(imageIn);
u = [];
v = [];
tic
%Compute Gx
%For every row use the mask (-1 0 1)
for i = 1:ny
u = imageIn(i,:);
v = zeros(1, nx);
for k = 2:nx-1
v(k) = (uint32(-1*u(k-1))+uint32(0*u(k))+uint32(u(k+1)));
end
v(1) = (uint32(-1*u(2))+uint32(0*u(1))+uint32(u(2)));
v(nx) = (uint32(-1*u(nx-1))+uint32(0*u(nx))+uint32(u(nx-1)));
imageGx(i,:) = v;
end
%For every column use the mask (1 1 1)
for j = 1:nx
u = imageGx(:,j);
v = zeros(ny, 1);
for k = 2:ny-1
v(k) = (uint32(u(k-1))+uint32(u(k))+uint32(u(k+1)));
end
v(1) = (uint32(u(2))+uint32(u(1))+uint32(u(2)));
v(ny) = (uint32(u(ny-1))+uint32(u(ny))+uint32(u(ny-1)));
imageGx(:,j) = v;
end
%Compute Gy
%For every row use the mask (1 1 1)
for i = 1:ny
u = imageIn(i,:);
v = zeros(1, nx);
for k = 2:nx-1
v(k) = (uint32(u(k-1))+uint32(u(k))+uint32(u(k+1)));
end
v(1) = (uint32(u(2))+uint32(u(1))+uint32(u(2)));
v(nx) = (uint32(u(nx-1))+uint32(u(nx))+uint32(u(nx-1)));
imageGy(i,:) = v;
end
%For every column use the mask (1 0 -1)
for j = 1:nx
u = imageGy(:,j);
v = zeros(ny, 1);
for k = 2:ny-1
v(k) = (uint32(u(k-1))+uint32(0*u(k))+uint32(-1*u(k+1)));
end
v(1) = (uint32(u(2))+uint32(0*u(1))+uint32(-1*u(2)));
v(ny) = (uint32(u(ny-1))+uint32(0*u(ny))+uint32(-1*u(ny-1)));
imageGy(:,j) = v;
end
toc
figure
imshow(imageGx, [0 255]);
figure
imshow(imageGy, [0 255]);
%Compute the magnitude G = sqrt(Gx^2 + Gy^2);
imageOut(:,:) = sqrt(imageGx(:,:).^2 + imageGy(:,:).^2);
figure
imshow(imageOut, [0 255]);
It's too bad you didn't use convn (convolution), since the weighted sum just screams it.
In a nutshell you produce Gx,Gy by using convn on the image matrix, using the appropriate kernels, as described in wikipedia
The solution was really obvious but took me some time to figure it out.
All I did is change the uint32 to int32 and be sure to perform the operations (e.g. multiplying by -1) after changing the values from uint32 to int32.
I'm trying to implement a very basic eigenface calculation in Matlab. It kind of works but I get only two meaningful eigenvalues - the rest are zero. The corresponding eigenvectors seem to be right since most of them will show an eigenface when converting to an image.
So why are most of my eigenvalues zero? I need them to be different from zero in order to sort the eigenfaces by their significance (greatest magnitude eigenvalues).
I am reading 400 images, each size h/w = 112/92 px
They can be found here: http://www.cl.cam.ac.uk/Research/DTG/attarchive/pub/data/att_faces.zip
The code:
clear all;
files = dir('eigenfaces2/training/*.pgm');
[numFaces, discard] = size(files);
h = 112;
w = 92;
s = h * w;
%calculate average face
avgFace = zeros(s, 1);
faces = [];
for i=1:numFaces
file = strcat('eigenfaces2/training/', files(i).name);
im = double(imread(file));
im = reshape(im, s, 1);
avgFace = avgFace + im;
faces(:,i) = im;
end
avgFace = avgFace ./ numFaces;
A = [];
for i=1:numFaces
diff = avgFace - faces(i);
A(:,i) = diff;
end
numEigs = 20;
L = (A' * A) / numFaces;
[tmpEigs, discard] = eigs(L, numEigs);
eigenfaces = [];
for i=1:numEigs
v = tmpEigs(:,i);
eigenfaces(:,i) = A * v;
end
%visualize largest eigenfaces
figure;
for i=1:numEigs
eigface = eigenfaces(:,i);
mmax = max(eigface);
mmin = min(eigface);
eigface = 255 .* (eigface-mmin) ./ (mmax-mmin);
eigface = reshape(eigface, h, w);
subplot(4,5,i); imshow(uint8(eigface));
end
I've don't have much experience with computer vision/image recognition, but I think you might want
diff = avgFace - faces(:,i);
in your second for loop. Otherwise it's just subtracting a constant from avgFace each time, and so A (and hence L) only gets a rank of 2.