To segment above image i want to use line height. I don't know even any algorithm for this. I want a useful link pls help..
just i want an efficient algorithm link for this.....
I shall be very thankful to you for this..
// i ahve tried till now
function [avmax avmin avgwidth]=firstsvg(Imag)
%Imag=imread('D:\THAPAR\poj\images\ndpj.jpg');
imtool(Imag);
G=Imag;
%xlswrite('G.xlsx',Imag(:,:,1));
[y,x]=size(G); % y dentoes rows and x denotes columns
T=160;%sum(sum(I))/(y*x)%T dentoes threshhold value - i.e avg
HYT=zeros(1,1);
GY=zeros(y,1); %single column of zeros
for j=1:y
for i=1:x
if (G(j,i)<T)
GY(j,1)=GY(j,1)+1; % count of no. of black pixel
end
end
end
for c=1:y
if (GY(c,1)> min)
min = GY(c,1);
gt(ce,1)=GY(c,1);
ce=ce+1;
end
end
dgt=zeros(ce,1);
for b=1:(ce-2)
dgt(b,1)= gt(b+1,1)- gt(b,1);
end
mdgt= mean(dgt);
avgwidth= thyt;
avmax =thyt;
avmin = gt(1,1);
just i want an algorithm link to calculate line height ???
Lets say you have image of M x N dimension where M is row and N is column. Perform logical OR for pixels in row. If you get 1, then you have atleast one black pixel in particular row.
Just see the number of consecutive 1's you are getting, it will be the approximate height of each sentence.
Related
I would like to calculate the median of each pixel in a set of images or "video". However, when MATLAB starts calculating this, it takes a very long time and finishes randomly with an index error. Why?
This is the code:
V = VideoReader('hall_monitor.avi');
info = get(V);
M = info.Width;
N = info.Height;
nb_frames_bk = 5;
v_pixel = zeros([nb_frames_bk 3]);
IB=zeros([M N 3],'double');
for i=1:M
for j=1:N
for k=1:nb_frames_bk
frm=read(V,k);
v_pixel(k,:)=frm(i,j,:);
end
IB(i,j,:)=median(v_pixel(:,:));
end
end
IB=uint8(IB);
imshow(IB);
This code can benefit from a lot of refactoring. For one thing, you are re-reading frames when you can just read them once, store them and use them after you're done.
Secondly, iterating over all pixels to compute your median is going to be very slow. From what it looks like in your code, for each spatial position over the first nb_frames_bk frames, you collect all of the RGB values within these frames and calculate the median RGB value.
Also as a minor note, you are getting a dimension exceeds error because you defined the output matrix wrong. You defined it as M x N with M being the width and N being the height. This needs to be swapped. Remember that matrices are defined as height first, width second. However, this is unnecessary with what I'm going to suggest for implementing this properly.
Instead of reading the frames one at a time, specify a range of frames. This way, you will get a 4D matrix where the first three dimensions references an image, with the fourth dimension representing the frame number. You can then take the median in the fourth dimension to find the median RGB value over all frames.
In other words, simply do this:
V = VideoReader('hall_monitor.avi');
nb_frames_bk = 5;
frms = read(V, [1 nb_frames_bk]);
IB = median(frms, 4);
imshow(IB);
This is much better, to the point and guaranteed to be faster. You also don't need to obtain the width and height of each frame as it is no longer needed as we are no longer looping over each pixel.
I would like to create a histogram of an image but without considering the first k pixels.
Eg: 50x70 image and k = 40, the histogram is calculated on the last 3460 pixels. The first 40 pixels of the image are ignored.
The order to scan the k pixels is a raster scan order (starting from the top left and proceeds by lines).
Another example is this, where k=3:
Obviously I can't assign a value to those k pixels otherwise the histogram would be incorrect.
Honestly I have no idea how to start.
How can I do that?
Thanks so much
The vectorized solution to your problem would be
function [trimmedHist]=histKtoEnd(image,k)
imageVec=reshape(image.',[],1); % Transform the image into a vector. Note that the image has to be transposed in order to achieve the correct order for your counting
imageWithoutKPixels=imageVec(k+1:end); % Create vector without first k pixels
trimmedHist=accumarray(imageWithoutKPixels,1); % Create the histogram using accumarray
If you got that function on your workingdirectory you can use
image=randi(4,4,4)
k=6;
trimmedHistogram=histKtoEnd(image,k)
to try it.
EDIT: If you just need the plot you can also use histogram(imageWithoutKPixels) in the 4th row of the function I wrote
One of the way can be this:
histogram = zeros(1,256);
skipcount = 0;
for i = 1:size(image,1)
for j = 1:size(image,2)
skipcount = skipcount + 1;
if (skipcount > 40)
histogram(1,image(i,j)+1) = histogram(1,image(i,j)+1) + 1;
end
end
end
If you need to skip some exact number of top lines, then you can skip the costly conditional check and just start the outer loop from appropriate index.
Vec = image(:).';
Vec = Vec(k+1:end);
Hist = zeros(1, 256);
for i=0:255
grayI = (Vec == i);
Hist(1, i+1) = sum(grayI(:));
end
First two lines drop the first k pixels so they are not considered in the computation.
Then you check how many 0's you have and save it in the array. The same for all gray levels.
In the hist vector, in the i-th cell you will have the number of occurance of gray level (i-1).
I have a gray scale image. I want to plot the median of the columns of that image on to the image axis. For doing this I need to have two things:
median values of the columns (which i can obtain using the Matlab's Median command) and
the position of median value in image coordinate.
Can anyone help me or give a hint or an idea or any function for estimating the median position?
This code marks all gray-scale level values in a given column equal to median value for that column:
load clown
M = median(X, 1);
figure();
imshow(uint8(X));
hold on;
for columnIdx = 1:numel(M)
medianValue = M(columnIdx);
% find locations of gray-scale lavel values equal to the median
idx = find(X(:, columnIdx) == medianValue);
if numel(idx) > 0
% mark all the gray-scale level values on the image
plot(ones(1,numel(idx)) * columnIdx, idx, '.g');
end
end
Hope it helps
I have a puzzle to solve which involves taking input which is size of grid. Grid is always square. Then a number of points on the grid are provided and the squares on the grid are 'taken' if they are immediately left or right or above or below.
Eg imagine a grid 10 x 10. If points are (1,1) bottom left and (10,10) top right, then if a point (2,1) is given then square positions left and right (10 squares) and above and below (another 9 squares) are taken. So using simple arithmetic, if grid is n squared then n + (n-1) squares will be taken on first point provided.
But it gets complicated if other points are provided as input. Eg if next point is eg (5,5) then another 19 squares will be 'taken' minus thos squares overlapping other point. so it gets complex. and of course a point say (3,1) could be provided which overlaps more.
Is there an algorithm for this type of problem?
Or is it simply a matter of holding a 2 dimensional array and placing an x for each taken square. then at end just totting up taken (or non-taken) squares. That would work but I was wndering if there is an easier way.
Keep two sets: X (storing all x-coords) and Y (storing all y-coords). The number of squares taken will be n * (|X| + |Y|) - |X| * |Y|. This follows because each unique x-coord removes a column of n squares, and each unique y-coord removes a row of n squares. But this counts the intersections of the removed rows and columns twice, so we subtract |X| * |Y| to account for this.
One way to do it is to keep track of the positions that are taken in some data structure, for example a set.
At the first step this involves adding n + (n - 1) squares to that data structure.
At the second (third, fourth) step etc this involves checking for each square at the horizontal and vertical line for the given (x, y) whether it's already in the data structure. If not then you add it to the data structure. Otherwise, if the point is already in there, then it was taken in an earlier step.
We can actually see that the first step is just a special case of the other rounds because in the first round no points are taken yet. So in general the algorithm is to keep track of the taken points and to add any new ones to a data structure.
So in pseudocode:
Create a data structure taken_points = empty data structure (e.g., a set)
Whenever you're processing a point (x, y):
Set a counter = 0.
Given a point (x, y):
for each point (px, py) on the horizontal and vertical lines that intersect with (x, y):
check if that point is already in taken_points
if it is, then do nothing
otherwise, add (px, py) to taken_points and increment counter
You've now updated taken_points to contain all the points that are taken so far and counter is the number of points that were taken in the most recent round.
Here is the way to do it without using large space:-
rowVisited[n] = {0}
colVisited[n] = {0}
totalrows = 0 and totalcol = 0 for total rows and columns visited
total = 0; // for point taken for x,y
given point (x,y)
if(!rowVisited[x]) {
total = total + n - totalcol;
}
if(!colVisited[y]) {
total = total + n-1 - totalrows + rowVisited[x];
}
if(!rowVisited[x]) {
rowVisited[x] = 1;
totalrows++;
}
if(!colVisited[x]) {
colVisited[x] = 1;
totalcol++;
}
print total
I have an image and I want to calculate the average gray value of different patches of the image.
I started with defining a patch using a row and column index. This is how I specify my where my subimage is located.
for x = 10 : 1 : 74
for y = 30 : 1 : 94
.........
end
end`
Now how do I calculate the average gray value of this subimage? I know that all this means is finding the mean(mean(image)). But since I have only the row and column positions, how can I apply this same concept.
try this
mean(mean(im(10:74,30:94)))
Assuming your image is some MxN matrix why don't you create a submatrix and calculate the mean over that?
eg:
subimage = image(10:74, 30:94);
mean_grey = mean(mean(subimage))
An alternative solution: convolve the image (I) with a flat kernel (h) (size of your 'sub-image') and take the value of the result at any index.
h = ones(a,b); % sub-image is size a x b
h = h / sum(h(:));
J = imfilter(I, h);
% J(x,y) will give you the average of a sub-image centered on (x,y)
Edge cases may cause strange behavior (sub-image out of image range), but you can supply a third argument to imfilter to address this.