How to process image before applying bwlabel? - matlab

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);

Related

Im trying to hide an image inside another using LSB but the resulting image is Coming out with high contrast

hello i wrote a simple code using a simple algorithm to understand steganography better , using LSB i hide the pixel values of one image into another, the key in this case represents the amount of steps (pixels) the loop will take to hide consecutive pixels from the secret cat image into the tree image.
I know it's not very secure but that's not the point.
My code to hide image:
% Function that accepts dir for secret image and dir for image to hide it in
% it writes an image that contains the secret image.
% it return an array containing the dimensions of the secret image
% because we need them in the revealing function
function [dim] = hideMyimg(secret,image,Key)
img = imread(image);
egg = imread(secret);
% Setting the least significant bits to zero
img = img - mod(img,4);
%checking if the secret fits into the hiding place
img = check(img,egg);
dim = [size(egg,1),size(egg,2)];
% using modulus to lower the amount of steps, to simplify code
key = mod(Key,1000);
%Seperating color channels
r1 = img(:,:,1);
g1 = img(:,:,2);
b1 = img(:,:,3);
r2 = egg(:,:,1);
g2 = egg(:,:,2);
b2 = egg(:,:,3);
%Driver code
r = hide(r1,r2,key);
g = hide(g1,g2,key);
b = hide(b1,b2,key);
%Combining the color channels
output(:,:,1) = r;
output(:,:,2) = g;
output(:,:,3) = b;
imwrite(output,'output.png')
end
%Function to hid matrix inside another
function [hidden] = hide(image,egg,key)
[row,col] = size(egg);
% turning the matrices into vectors to make it easy to loop over
imgvec = image(:);
% Move the most significant bits of the secret image to the least significant bits
tempi = egg./64;
eggvec = tempi(:);
%max value of pixels to hide
max = row*col;
% counter to make sure the loop stops once all the pixels are hidden
i = 1;
% temp value we need to re-loop over the matrix from a new starting point
temp = 2;
%counter
n = 1;
while(i<max)
imgvec(n) = imgvec(n) + eggvec(i);
n = n + key;
if n>max
n = temp;
temp = temp + 1;
end
i = i + 1;
end
hidden = reshape(imgvec,[size(image,1),size(image,2)]);
end
% Function to check if image 1 is bigger than image 2
% And if so resize image 1 to be bigger than image 2
function [image] = check(img1,img2)
row1 = size(img1,1);
col1 = size(img1,2);
row2 = size(img2,1);
col2 = size(img2,2);
if row2*col2>row1*col1
val1 = ceil(row2/row1);
val2 = ceil(col2/col1);
if val1 > val2
image = imresize(img1,val1);
else
image = imresize(img1,val2);
end
else
image = img1;
disp('yes')
end
end
code to reveal image hidden:
function [] = getMyimg(key,dim)
image = imread('output.png');
%seperating color channels
r = image(:,:,1);
g = image(:,:,2);
b = image(:,:,3);
row = dim(1);
col = dim(2);
egg(:,:,1) = getimg(r,key,row,col);
egg(:,:,2) = getimg(g,key,row,col);
egg(:,:,3) = getimg(b,key,row,col);
% move least significant bits to the most significant
egg = egg * 64;
imwrite(egg,'secret.png');
end
function [egg] = getimg(image,key,row,col)
imgvec = image(:);
%initializing vector with the right dimensions for the secret image
eggvec = zeros(row*col,1);
max = row*col;
i = 1;
n = 1;
temp = 2;
while i < max
%get the least significant bits
eggvec(i) = mod(imgvec(n),4);
n = n + key;
if n>max
n = temp;
temp = temp + 1;
end
i = i + 1;
end
egg = reshape(eggvec,[row,col]);
end
resulting image:
why is it coming out like this?

Aligning RGB Channels (using SSD) of the given image to produce colored and properly aligned and clear image

The problem statement is - To search over a window of possible displacements (You will search [-10,10] pixels), score each one using some image matching metric, and take the displacement with the best score. The simplest one is the Sum of Squared Differences (SSD) distance, which simply subtracts one image region from the other and evaluates the sum of the squared values in each pixel. You need to do SSD based calculations on image regions which are of double type.
As R,G,B channels are highly correlated to each other, SSD metric is very likely to work. Your task is to hold the G channel as the reference and move around R and B channels over it and keep track of the SSD value for the 51x51 image regions at the center of the channels. For each channel, you will find the (x,y) displacement vector that gives the minimum SSD value.
The program should divide the image into three equal parts. The first image is Blue Channel, the second one is Green channel and the last one is Red channel.
You have to name your variables as below
Blue channel Image - B
Green channel Image - G
Red channel Image - R
Reference Green Channel center region (51x51) - ref_img_region (center of this region coincides with the center of image and indexes are always integers)
Final aligned image - ColorImg_aligned
Given input image-
Required output image-
I have done this so far and getting the almost same output as required but the compiler is showing incorrect value for ColorImg_aligned.
What's wrong with my code. I am new to Matlab. Sorry if the code is not efficient.
%Read the image
img = imread('course1image.jpg');
[r,c] = size(img);
B = img(1:r/3,:);
G = img((r/3)+1:(2*r/3),:);
R = img((2*r/3)+1:r,:);
ref_img_region = G;
[rg,cg] = size(ref_img_region);
ref_img_region = ref_img_region(ceil((rg-50)/2) :ceil((rg-50)/2) + 50,ceil((cg-50)/2) :ceil((cg-50)/2) + 50);
%disp(size(ref_img_region));
ref_img_region = double(ref_img_region);
% Naive way
% ColorImg_aligned = cat(3,R,G,B);
% imshow(ColorImg_aligned);
% SSD way
nR = align(G,R);
nB = align(G,B);
ColorImg_aligned = cat(3,nR,G,nB);
imshow(ColorImg_aligned);
function aligned = align(green,red)
[red_row,red_col] = size(red);
[green_row,green_col] = size(green);
% checking SSD for cropped part of the images for faster calculation
cropped_red = red(ceil((red_row-50)/2) : ceil((red_row-50)/2) + 50,ceil((red_col-50)/2) :ceil((red_col-50)/2) + 50);
cropped_green = green(ceil((green_row-50)/2) : ceil((green_row-50)/2) + 50,ceil((green_col-50)/2) :ceil((green_col-50)/2) + 50);
MiN = 9999999999;
r_index = 0;
r_dim = 1;
for i = -10:10
for j = 1:2
ssd = SSD(cropped_green,circshift(cropped_red,i,j));
if ssd < MiN
MiN = ssd;
r_index = i;
r_dim = j;
end
end
end
aligned = circshift(red,r_index,r_dim);
end
function ssd = SSD(a1,a2)
x = double(a1)-double(a2);
ssd = sum(x(:).^2);
end
Finally I was able to pass the assignment.
I just changed Y = circshift(A,K,dim)version of circshift to Y = circshift(A,[i,j])I'm still doing the same thing but the compiler accepted the answer this time.
Anybody having thoughts about why this happened?
After modification the code looks like this.
%Read the image
img = imread('course1image.jpg');
[r,c] = size(img);
B = img(1:r/3,:);
G = img((r/3)+1:(2*r/3),:);
R = img((2*r/3)+1:r,:);
ref_img_region = G;
[rg,cg] = size(ref_img_region);
ref_img_region = ref_img_region(ceil((rg-50)/2) :ceil((rg-50)/2) + 50,ceil((cg-50)/2) :ceil((cg-50)/2) + 50);
%disp(size(ref_img_region));
ref_img_region = double(ref_img_region);
% Naive way
% ColorImg_aligned = cat(3,R,G,B);
% imshow(ColorImg_aligned);
% SSD way
nR = align(G,R);
nB = align(G,B);
ColorImg_aligned = cat(3,nR,G,nB);
imshow(ColorImg_aligned);
function aligned = align(green,red)
[red_row,red_col] = size(red);
[green_row,green_col] = size(green);
% checking SSD for cropped part of the images for faster calculation
cropped_red = red(ceil((red_row-50)/2) : ceil((red_row-50)/2) + 50,ceil((red_col-50)/2) :ceil((red_col-50)/2) + 50);
cropped_green = green(ceil((green_row-50)/2) : ceil((green_row-50)/2) + 50,ceil((green_col-50)/2) :ceil((green_col-50)/2) + 50);
MiN = 9999999999;
r_index = 0;
r_dim = 1;
% Modifications
for i = -10:10
for j = -10:10
ssd =
SSD(cropped_green,circshift(cropped_red,[i,j])); %circshift(A,[i,j])
if ssd < MiN
MiN = ssd;
r_index = i;
r_dim = j;
end
end
end
aligned = circshift(red,[r_index,r_dim]);
end
function ssd = SSD(a1,a2)
x = double(a1)-double(a2);
ssd = sum(x(:).^2);
end
Output

Local Interest Point Detection using Difference of Gaussian in Matlab

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?

Running matlab code through a folder

I have the following code for which instead of loading one image at a time, I'd like to run through every image in a folder (the defective folder in this code). I'd like the output to be an array containing the values of 'G' for each of the input images. I'm not too sure how to go about this - so any points appreciated. Many thanks!
%PCA code,
img = imread('C:\users\m7-miller\desktop\250images\defective\inkblob01.png');
img_gray = rgb2gray(img);
img_gray_double = im2double(img_gray);
figure,
set(gcf,'numbertitle','off','name','Grayscale Image'),
imshow(img_gray_double)
%find mean of the image
img_mean = mean(img_gray_double);
[m n] = size(img_gray);
%Make column vector of mean image value
new_mean = repmat(img_mean,m,1);
%Mean corrected image
Corrected_img = img_gray_double - new_mean;
%Covariance matrix of corrected image
cov_img = cov(Corrected_img);
%Eigenvalues of covariance matrix - columns of V are e-vectors,
%diagonals of D e-values
[V, D] = eig(cov_img);
V_T = transpose(V);
Corrected_image_T = transpose(Corrected_img);
FinalData = V_T * Corrected_image_T;
% Image approximation by choosing only a selection of principal components
PCs = 3;
PCs = n - PCs;
Reduced_V = V;
for i = 1:PCs,
Reduced_V(:,1) =[];
end
Y=Reduced_V'* Corrected_image_T;
Compressed_img = Reduced_V*Y;
Compressed_img = Compressed_img' + new_mean;
figure,
set(gcf,'numbertitle','off','name','Compressed Image'),
imshow(Compressed_img)
% End of image compression
% Difference of original image and compressed
S = (img_gray_double - Compressed_img);
figure,
set(gcf,'numbertitle','off','name','Difference'),
imshow(S)
% Sum of the differences
F = sum(S);
G = sum(F)
Are you looking for the dir command?
files = dir('*.png');
for n=1:size(files,1)
filename = files(n).name;
img = imread(filename);
....
G = sum(F);
end

Average filter in matlab

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);