First pixel of the image - image

I just scanned a sample image and I'm trying to detect the first pixel which has a value of "0" in the binary-image.
I used paint to write a text and when i used the following prog, it always catches the bottom most pixel.
clear all;
x=imread('textjay.png');
y=im2bw(x);
height=size(y,1); % row
width=size(y,2); % col
valueoftheindex=0;
pixel_value=0;
for i=1:width
for j=1:height
pixel_value=y(j,i);
if (pixel_value==0)
valueofthewidth=i;
valueofthehieght=j;
break
end
end
end
valueofthewidth
valueofthehieght
imtool(y)

This depends a lot on what you consider to be "the first pixel".
Assuming that you can live with the pixel order that MATLAB assigns you could use
idx = find(y == 0, 1, 'first')
[row_idx, col_idx] = ind2sub(size(y), idx)
For other measures of "firstness" you would have to either transpose the input matrix (the image), or resort to some more refined way of calculation.
And yes, the break will only break the inner loop, as dawe already pointed out.

Related

Importing Stack of Images

So I have the code to import a stack of images, but I am getting an error: Subscripted assignment dimension mismatch.
myPath = 'E:\folder name\'; %'
fileNames = dir(fullfile(myPath, '*.tif'));
width = 1400;
height = 1050;
nbImages = length(fileNames);
C=uint8(zeros(width, height, nbImages));
for i=1:length(fileNames)
C(:,:,i)=imread(cat(2,'E:\folder name\',fileNames(i).name));
i
end
I understand that the error is originating from the for loop, but I don't know of any other way to fill in an empty matrix with images.
Your images must not be all the same size. You can handle this by using explicit assignment for the first two dimensions. This will zero-pad any images which are smaller than the rest.
im = imread(...);
C(1:size(im, 1), 1:size(im, 2), i) = im;
Also, there is a good chance that your images have multiple color channels (the third dimension), so you'll likely want to concatenate along the fourth dimension rather than the third.
C(:,:,:,i) = imread(...)
Obviously it all depends what you want to do with the images, but in general, if you want a "stack" of images (or a "stack" of anything, really), then it sounds like you should be collecting them as a cell array instead.
Also, the correct way to create safe filenames is using the fullfile command
e.g.
C = cell(1, length(nbImages));
for i = 1 : length (fileNames)
C{i} = imread (fullfile ('E:','folder name', fileNames(i).name));
end
If you really want to concatenate to a 3D matrix from your cell array, assuming you have checked this is possible, you can do this very easily using comma-separated-list generator syntax:
My3DMatrix = cat(3, C{:});

Motion History Image (MHI) in Matlab

My project is to detect human activity through stored video clips.
I am successfully able to do the following:
Get the Motion History Image (MHI) from a video using OpenCV
Train and classify the set of images using Matlab
However, I want to use Matlab in order to get the Motion History Image (MHI). Is it possible, and if yes can someone guide me? Thank you.
I have attached a sample Motion History Image (MHI)
I have used the following code for MHI:
http://www.ece.iastate.edu/~alexs/classes/2007_Fall_401/code/09_MotionHistory/motempl.c
MHI is just a ways of implementing motion detection (and uses silhouettes as the basis of it).
Let suppose that the silhouette of the most recent object has been created. It also uses a timestamp to identify if the current silhouette is recent or not. The older silhouettes have to be compared with the current silhouette in order to achieve movement detection. Hence, earlier silhouettes are also saved in the image, with an earlier timestamp.
MHI describes the changes of some moving objects over the image sequence. Basically, you should only maintain an image where every pixel encodes a time information - whether the silhouette is recent or not or where the movement occurs at a given time.
Therefore the implementation of MHI is very simple e.g.:
function MHI = MHI(fg)
% Initialize the output, MHI a.k.a. H(x,y,t,T)
MHI = fg;
% Define MHI parameter T
T = 15; % # of frames being considered; maximal value of MHI.
% Load the first frame
frame1 = fg{1};
% Get dimensions of the frames
[y_max x_max] = size(frame1);
% Compute H(x,y,1,T) (the first MHI)
MHI{1} = fg{1} .* T;
% Start global loop for each frame
for frameIndex = 2:length(fg)
%Load current frame from image cell
frame = fg{frameIndex};
% Begin looping through each point
for y = 1:y_max
for x = 1:x_max
if (frame(y,x) == 255)
MHI{frameIndex}(y,x) = T;
else
if (MHI{frameIndex-1}(y,x) > 1)
MHI{frameIndex}(y,x) = MHI{frameIndex-1}(y,x) - 1;
else
MHI{frameIndex}(y,x) = 0;
end
end
end
end
end
Code from: https://searchcode.com/codesearch/view/8509149/
Update #1:
Try to draw it as follows:
% showMHI.m
% Input frame number and motion history vector to display normalized MHI
% at the specified frame.
function showMHI(n, motion_history)
frameDisp = motion_history{n};
frameDisp = double(frameDisp);
frameDisp = frameDisp ./ 15;
figure, imshow(frameDisp)
title('MHI Image');

Removing Noise From an image in MATLAB

I'm using Geometric mean filter to remove noise instead of median filter as image quality goes off in former case. code shown below is a part of m-file to remove noise.
fname = getappdata(0, 'fname');
[a, map] = imread(fname);
x = ind2rgb(a, map);
b = im2double(x);
w=fspecial('gaussian',[3,3]);
geom=exp(imfilter(log(b),ones(3,3),'replicate')).^(1/3/3);
fname=imfilter(b,w,'replicate');
axes(handles.axes1);
imshow(fname);
If i press push button which is named 'Remove Noise' above code get executed irrespective of image quality/property. In the sense even if no noise is present, image will be subjected to filter.
My question, is there any way to detect whether noise is present or not, so that the moment i pressed push button if no Noise in image it should display a message stating 'NO NOISE TO REMOVE' automatically.
There is no direct way to determine whether an image is noisy or not.
However, you can compare resulting image fname with the input image b in such a way that if their difference is lower than a certain threshold, then it can be decided that denoising operation has not changed image effectively and there is not much noise in the original image like:
threshold_ratio = 0.2; % to be decided experimentally
difference_ratio = sum(sum((fname - b).^2)) / sum(sum(b.^2));
if difference_ratio < threshold_ratio
disp('NO NOISE TO REMOVE');
end

Representing Variable Filter size in MATLAB

I am working on a filter in which the instead of using fixed size filtering window, I use a adaptive window size based on noise density. For example, let say the window size is 3x3, it has 9 pixels. when all these 9 pixels are detected as corrupted pixels it is useless to proceed to next step as I need some noisy free pixels in window to process next step. In this case, I change the window size to 5x5 and scan again. If once again all the pixels(25 pixels) are detected as corrupted, I go for 7x7 window. To implement I have written a code but it is too large as I represented all the elements in each window. I am unsure to implement it otherwise but I am sure there will other easy way to do it.
The Code, I written for the above stated purpose is
if((S1==1) && (S2==1))
5x5 window===> V=[L(p-2,q-2) L(p-2,q-1) L(p-2,q) L(p-2,q+1) L(p-2,q+2) L(p-1,q-2) L(p-1,q-1) L(p-1,q) L(p-1,q+1) L(p-1,q+2) L(p,q-2) L(p,q-1) L(p,q+1) L(p,q+2) L(p+1,q-2) L(p+1,q-1) L(p+1,q) L(p+1,q+1) L(p+1,q+2) L(p+2,q-2) L(p+2,q-1) L(p+2,q) L(p+2,q+1) L(p+2,q+2)]; % 5x5 window
for k=1:24
if((V(k) == 0) || (V(k) == 255))
else
N(a)=V(k);
a=a+1;
end
end
if((a-1)>= 1)
Y(p,q)=round(Median(N(1:a-1)));
%disp(Y(p,q));
a=1;
else
7x7 window===> V1=[L(p-3,q-3) L(p-3,q-2) L(p-3,q-1) L(p-3,q) L(p-3,q+1) L(p-3,q+2) L(p-3,q+3) L(p-2,q-3) L(p-2,q-2) L(p-2,q-1) L(p-2,q) L(p-2,q+1) L(p-2,q+2) L(p-2,q+3) L(p-1,q-3) L(p-1,q-2) L(p-1,q-1) L(p-1,q) L(p-1,q+1) L(p-1,q+2) L(p-1,q+3) L(p,q-3) L(p,q-2) L(p,q-1) L(p,q+1) L(p,q+2) L(p,q+3) L(p+1,q-3) L(p+1,q-2) L(p+1,q-1) L(p+1,q) L(p+1,q+1) L(p+1,q+2) L(p+1,q+3) L(p+2,q-3) L(p+2,q-2) L(p+2,q-1) L(p+2,q) L(p+2,q+1) L(p+2,q+2) L(p+2,q+3) L(p+3,q-3) L(p+3,q-2) L(p+3,q-1) L(p+3,q) L(p+3,q+1) L(p+3,q+2) L(p+3,q+3)]; % 7x7 window
Similarly, I have used windows upto 11x11. I want to represent V and V1 vector easily rather than writing these much of codes.
An arbitrary window centered at [p,q] of size n can be read from an image as
halfSize = floor(n/2); %# n has to be odd
window = image(p-halfSize:p+halfSize,q-halfSize:q+halfSize);
Note that you want to pad your image with the maximum value of halfSize, or alternatively, test that e.g. p>halfSize and p<imageSize-halfSize+1 (same for q), so that you don't get indexing errors.

How would I detect horizontal-black lines using ImageMagick?

So I have what is essentially a spreadsheet in TIFF format. There is some uniformity to it...for example, all the column widths are the same. I want to de-limit this sheet by those known-column widths and basically create lots of little graphic files, one for each cell, and run OCR on them and store it into a database. The problem is that the horizontal lines are not all the same height, so I need to use some kind of graphics library command to check if every pixel across is the same color (i.e. black). And if so, then I know I've reached the height-delimiter for a cell. How would I go about doing that? (I'm using RMagick)
Use image#get_pixel: http://www.simplesystems.org/RMagick/doc/image2.html#get_pixels
Warning: Those docs are old, so it may have changed in the newer versions. Look at your own rdocs using $ gem server, assuming they have rdocs.
image#rows gives you the height of the image, then you can do something like (untested):
def black_line?(pixels)
pixels.each do |pixel|
unless pixel.red == 0 && pixel.green == 0 && pixel.blue == 0
return false
end
end
true
end
black_line_heights = []
height = image.rows
width = image.columns
height.times do |y|
pixels = image.get_pixel(0,y,width,1)
black_line_heights << y if black_line?(pixels)
end
Please keep in mind that I'm not sure about the api. Looking at older docs, and I can't test it now. But it looks like the general approach you would take. BTW, it assumes the row borders are 1 pixel thick. If not, change the 1 to the actual thickness and that might be enough to make it work like you expect.
Ehsanul had it almost right...the call is get_pixels, which takes in as arguments x,y,w,h and returns an array of those pixels. If the dimension is 1 thick, you'll get a nice one-d array.
Since the black in a document can vary, I altered Ehsanul's method a little bit to detect whether consecutive pixels were roughly the same color. AFter a 100 or so pixels, it's probably a line:
def solid_line?(pixels, opt={}, black_val = 10)
last_pixel = nil
thresh = opt[:threshold].blank? ? 4 : opt[:threshold]
pixels.each do |pix|
pixel = [pix.red, pix.green, pix.blue]
if last_pixel != nil
return false if pixel.reject{|p| (p-last_pixel[pixel.index(p)]).abs < thresh && p < black_val}.length > 0
end
last_pixel = pixel
end
true
end

Resources