Matlab - Replace successive pixel with pixel from the left - matlab

So, I've quantized a grayscale image with four quantized values. I'm trying to maintain the first pixel of each row of the quantized image and replace each successive pixel with the difference from the pixel to its left.
How would you code this in matlab and can someone explain this to me conceptually?
Also, my concern is that because the image is relatively uniform because of the quantization of the dynamic range, most of the image would appear black, no? It seems to me that only the transition areas and the edges will have some difference in quantized values.

To create the difference to the pixel on the left, all you have to do is subtract the pixels in columns 1,2,3... from the columns 2,3,4...
%# create a random image with four values
randomImage = randi(4,[100,90]); %# use different numbers of rows and cols so we know which is which
%# catenate the first column of the image with the difference from the pixel to the left
%# for all pairs of columns in the image
differenceImage = [randomImage(:,1),randomImage(:,1:end-1)-randomImage(:,2:end)];
Yes, you'd expect quite a few uniform patches (which will be gray, since unless you plot the absolute value of the differences, there will be some that are negative).

Related

Mutual Information, Kullback Leibler Divergence between two color images

I am working on a project on Image classification using Mutual Information. It requires me to use probability distribution of a color image, either I want to calculate the Mutual Information or the Kullback Leibler Divergence in Matlab. Can anyone help me out in this?
I have calculated the entropy of a colored image as:
I = imread('s1.png');
% rgb_columns = reshape(rgb, [], 3);
% %Change RGB matrices to a single matrix of color indices.
% %Removes the third dimension from the pixel intensity matrix.
Color_ind=double(I(:,:,1)).*256^2+double(I(:,:,2).*256)+double(I(:,:,3));
disp(size(Color_ind));
% Finding unique elements in the matrix and find their length
unique_ind=unique(Color_ind);
unique_len=length(unique_ind);
%Pre-allocate space for the vector that will hold the number of entries
%for each unique color
color_count_prob=zeros(unique_len,1);
%Count the number of each occurrence of each unique color index in the
%original matrix.
for i = 1:unique_len
color_count_prob(i)=(length(find(unique_ind(i)==Color_ind)))/(2073600);
end
en_sum=0;
for i = 1:unique_len
en_sum = en_sum + log2(color_count_prob(i));
end
en = -en_sum;
For PDF calculation of a colored image:
First, you need to convert the image to grayscale. If you insist on staying in RGB mode (or any other colored mode) you will have to generate 3 PDFs (one for each color channel) - I would not suggest doing that for the purposes of Kullback Liebler or Mutual Information, the grayscale image will do.
Second, you need to calculate the distribution of each image. For this purpose, you will need to flatten your image (convert from a 2D array to 1D array). Once you flatten the image, you should sort the values. Once sorted, you should normalize them (you can choose not to, but would recommend). After that, you can derive the histogram for the image.
And to measure the Kullback Liebler divergence, you need:
Measure the entropy on your image histograms. This will be a number.
Simply subtract the values from step one and it will give you the Kullback Liebler divergence value for those two images.

How to create a mask to segment a color image by activecontour?

I want to use the function activecontour in matlab to segment a color image, but I don't know how to create the mask.
The documentation says:
For color and multi-channel images, mask must be a 2-D logical array where the first two dimensions match the first two dimensions of the image A.
But I don't understand what has to be done. Any suggestions?
Let's consider that the size of your image is NxM pixels, N is the number of rows, M the number of columns.
If it is a color image, each pixel is probably composed of 3 values, one for intensity of red (R), one intensity of blue (B) and one for intensity of green (G). These are called the color channels. So the real shape of the matrix representing your image is NxMx3.
What the documentation says is that the mask should be 2-D, and the dimensions should match the first two dimension of your image. It means the mask should have the same number of rows and cols than your image, but each pixel of the mask is not composed of 3 values anymore. It is composed of 1 value (a logical value : 0 or 1).
So what you need to do is to give the function a matrix NxM with only 0 and 1 as possible values. The doc says that the mask is the :
Initial contour at which the evolution of the segmentation begins, specified as a binary image the same size as A.
So the mask needs to represent an initial guess of the contour. If you already know that what you want to see is in the upper left corner of the image, you can set the initial contour as a square located in the upper left corner for example.
Now to represent the contour by a matrix of logicals, you simply set all the elements of the matrix to 0 and just the elements representing the contour to 1 I guess.
Lets me know if there is something you don't understand, I'd be glad to answer you.

How to find all the blue pixels and the location of the two boundaries in blue pixels?

I want to find per column the first and last blue pixels and them find the other boundary ( first and last blue pixel rows) inside this rows achieved before.
I made the alterations based on the previous answeers, but now I have this error when it tries to find the bif_first and last: Subscripted assignment dimension mismatch. bif_first2(2,z)=find(dx(:,z)==1,2,'first');
What is wrong? Please see my code below:
rgbImage_blue=zeros(size(movingRegistered));
lumen_first=zeros(1,size(movingRegistered,2)); lumen_last=zeros(1,size(movingRegistered,2)); bif_first=zeros(1,size(movingRegistered,2)); bif_last=zeros(1,size(movingRegistered,2)); bif_last2=zeros(2,size(movingRegistered,2)); bif_first2=zeros(2,size(movingRegistered,2));
blue=cat(3,0,0,255);
ix=all(bsxfun(#eq,movingRegistered,blue),3);% find all the blue pixels, and put them at 1 % logical array of where blue pixels are dx=[zeros(1,size(movingRegistered,2));diff(ix)]; % zeros to make the same number of columns and rows % the difference by row for all columns
nTops=sum(dx==1); % the transitions to blue
nBots=sum(dx==-1); % and from blue... % see if are consistent; if not, something's not right in image
if(nTops~=nBots), error('Mismatch in Top/Bottom'),end
for z=1:1:size(movingRegistered,2);
if nTops(1,z)==2; bifurcation=false;lumen=true; %only existis two boundaries no bifurcation
lumen_first(1,z)=find(ix(:,z)==1,1,'first');
lumen_last(1,z)=find(ix(:,z)==1,1,'last');
end
if nTops(1,z)>2;
bifurcation=true;
lumen_first(1,z)=find(ix(:,z)==1,1,'first');
lumen_last(1,z)=find(ix(:,z)==1,1,'last');
bif_first2(2,z)=find(dx(:,z)==1,2,'first');
bif_first(1,z)=bif_first2(2,z);
bif_last2(2,z)=find(dx(:,z)==1,2,'last');
bif_last(1,z)=bif_last2(2,z);
end
end
Your problem is you are comparing a n*m*3 image with a 3*1 vector. This operation is not defined.
Use this code:
blue=cat(3,0,0,250)
ix=all(bsxfun(#eq,movingRegistered,blue),3)
Images in Matlab use the third dimension for color, that's why I created blue to be a 1*1*3 vector. Now this vector is compared to the image, using bsxfun to expand the vector to match the image size. This operation compares each color channel individually, so all is used to collect the data for all three channels.

How to search a gray scale image?

I have 10 gray scale images<2559*3105>. These images are taken from X-ray reflectivity measurement. Each image has two spots except first, showing intensity of X-ray. First image has one highest intensity spot. From second to tenth image each has two spots first one is same as in the first image but second one differs with respect to the location and intensity value. I want to search and crop these spots. The problem is when i apply a condition that find() maximum intensity point in the image, it always points to the spot which is common in all images.
here's some basic image processing code that allows you to select the indices of the spots
%# read the image
im=rgb2gray(imread('a.jpg'));
%# select only relevant area
d=im(5:545,5:660);
%# set a threshold and filter
thres = (max([min(max(d,[],1)) min(max(d,[],2))])) ;
filt=fspecial('gaussian', 7,1);
% reduce noise threshold and smooth the image
d=medfilt2(d);
d=d.*uint8(d>thres);
d=conv2(double(d),filt,'same') ;
d=d.*(d>thres);
% find coonected objets 1
L = bwlabel(d);
%# or also
CC = bwconncomp(d);
Both L and CC have information about the indices of the 2 blobs, so you can now select only that part of the image using them

How to extract and recognize the vehicle plate number with matlab?

I want to develop a matlab program that can extract and recognize the plate number of vehicle with template matching method.
Here is my code:
function letters = PengenalanPlatMobil(citra)
%load NewTemplates
%global NewTemplates
citra=imresize(citra,[400 NaN]); % Resizing the image keeping aspect ratio same.
citra_bw=rgb2gray(citra); % Converting the RGB (color) image to gray (intensity).
citra_filt=medfilt2(citra_bw,[3 3]); % Median filtering to remove noise.
se=strel('disk',1);
citra_dilasi=imdilate(citra_filt,se); % Dilating the gray image with the structural element.
citra_eroding=imerode(citra_filt,se); % Eroding the gray image with structural element.
citra_edge_enhacement=imsubtract(citra_dilasi,citra_eroding); % Morphological Gradient for edges enhancement.
imshow(citra_edge_enhacement);
citra_edge_enhacement_double=mat2gray(double(citra_edge_enhacement)); % Converting the class to double.
citra_double_konv=conv2(citra_edge_enhacement_double,[1 1;1 1]); % Convolution of the double image f
citra_intens=imadjust(citra_double_konv,[0.5 0.7],[0 1],0.1); % Intensity scaling between the range 0 to 1.
citra_logic=logical(citra_intens); % Conversion of the class from double to binary.
% Eliminating the possible horizontal lines from the output image of regiongrow
% that could be edges of license plate.
citra_line_delete=imsubtract(citra_logic, (imerode(citra_logic,strel('line',50,0))));
% Filling all the regions of the image.
citra_fill=imfill(citra_line_delete,'holes');
% Thinning the image to ensure character isolation.
citra_thinning_eroding=imerode((bwmorph(citra_fill,'thin',1)),(strel('line',3,90)));
%Selecting all the regions that are of pixel area more than 100.
citra_final=bwareaopen(citra_thinning_eroding,125);
[labelled jml] = bwlabel(citra_final);
% Uncomment to make compitable with the previous versions of MATLAB®
% Two properties 'BoundingBox' and binary 'Image' corresponding to these
% Bounding boxes are acquired.
Iprops=regionprops(labelled,'BoundingBox','Image');
%%% OCR STEP
[letter{1:jml}]=deal([]);
[gambar{1:jml}]=deal([]);
for ii=1:jml
gambar= Iprops(ii).Image;
letter{ii}=readLetter(gambar);
% imshow(gambar);
%
end
end
but the number recognized is always wrong and too much is detected or sometimes too little.
How to fix it?
Here is the images and this one
For number plate extraction you have to follow this algorithm(I used this in my project)
1. Find Histogram variation horizontally(by using imhist)
2. Find the part of histogram where you get maximum variation and get x1 and x2 value.
3. crop that image horizontally by using value of x1 and x2.
4. Repeat same process for vertical cropping.
Explanation:
In order to remove unnecessary information from the image, it requires only edges of the image to work. For detection of the edges, we make use of a built-in MATLAB function. But first we convert the original image to grayscale image.
This grayscale image is converted to binary image by determining a threshold for different intensities in the image. After binarization only, edge detection algorithm can be used. Here we have used ‘ROBERTS’. After extensive testing, it seemed our application the best. Then to determine the region of license plate we have done horizontal and vertical edge processing. First the horizontal histogram is calculated by traversing each column of an image. The algorithm starts traversing with the second pixel from the top of each column of image matrix. The difference between second and first pixel is calculated. If the difference exceeds certain threshold, it is added to total sum of differences. It traverses until the end of the column and the total sum of differences between neighbouring pixels are calculated. At the end, a matrix of the column-wise sum is created. The same process is carried out for vertical histogram. In this case, instead of columns, rows are processed.
After calculating horizontal and vertical histogram we have calculated a threshold value which is 0.434 times of maximum horizontal histogram value. Our next step for extraction is cropping the area of interest i.e. number plate area. For cropping we first crop original image horizontally and then vertically. In horizontal cropping we process image matrix column wise and compare its horizontal histogram value with the predefined threshold value. If certain value in horizontal histogram is more than threshold we mark it as our starting point for cropping and continue until threshold value we find-less than that is our end point. In this process we get many areas which have value more than threshold so we store all starting and end point in a matrix and compare width of each area, width is calculated difference of starting and end point. After that we find set of that staring and end point which map largest width. Then we crop image horizontally by using that starting and end point. This new horizontally cropped image is processed for vertical cropping. In vertical cropping we use same threshold comparison method but only difference is that this time we process image matrix row wise and compare threshold value with vertical histogram values. Again we get different sets of vertical start and end point again we find that set which map largest height and crop image by using that vertical start and end point. After vertical and horizontal cropping we get exact area of number plate from original image in RGB format.
For Recognition use template matching with correlation(using corr2() in matlab)
I would change the loop following character detection to
[gambar{1:jml}]=deal([]);
for ii=1:jml
gambar{ii}= Iprops(ii).Image;
%letter{ii}=readLetter(gambar);
imshow(gambar{ii});
end
I think what you want to do at this point is either
(1) pick the roi in advance before applying character extraction and ocr.
or
(2) apply ocr to all of the characters from the entire image and then use proximity rules or other rules to identify the license plate number.
Edit:
If you run the following loop after character extraction you can get an idea what I mean by "proximity":
[xn yn]=size(citra); % <-- citra is the original image matrix
figure, hold on
[gambar{1:jml}]=deal([]);
for ii=1:jml
gambar{ii}= double(Iprops(ii).Image)*255;
bb=Iprops(ii).BoundingBox;
image([bb(1) bb(1)+bb(3)],[yn-bb(2) yn-bb(2)-bb(4)],gambar{ii});
end
Here is the image after edge detection:
and after character extraction (after running the loop above):