I have a matrix (with the size of A and B; suppose 100x100) and want to fill in with smaller matrix (or block) with the size of a and b (suppose 12x12).
As it is clear, the loop starts from "j" and then goes to the next row. Actually I want to use the same loop, by adding another variable to impose that it first complete the columns. Any idea that how I should define this new variable in the following loop to control the completion direction.
M = zeros(100,100);
for j = 1:12:100-12+1
for i = 1:12:100-12+1
block = rand(12,12);
M(i:i+11, j:j+11) = block;
imagesc(M); axis equal tight xy
pause(.1)
end;
end;
Why not just do
M = zeros(100,100);
for j = 1:12:100-12+1
for i = 1:12:100-12+1
block = rand(12,12);
M(i:i+11, j:j+11) = block;
imagesc(M); axis equal tight xy
pause(.1)
end;
end;
Now you will iterate over the i's first.
Incidentally, I recommend not using i and j as loop variables - they shadow the built in sqrt(-1) imaginary number...
update based on your comment, it seems you want to leave the order of i and j in the outer loop, and add "another parameter" to change the direction. The following code does all that. Is this what you are after?
M = zeros(100,100);
rowFirst = true; % set to false for "column first"
for i = 1:12:100-12+1
for j = 1:12:100-12+1
block = rand(12,12);
if rowFirst
M((0:11) + i, (0:11) + j) = block;
else
M((0:11) + j, (0:11) + i) = block;
end
imagesc(M); axis equal tight xy
pause(.1)
end
end
update 2 and now "even for non square matrix" (not tested, late at night):
M = zeros(100, 120);
rowFirst = true;
sz = size(M);
blockSize = 12;
v = 1:blockSize;
nrc = floor(sz / blockSize);
if rowFirst
nrc = reverse(nrc);
end
for ii = blockSize * (0:nrc(1)-1)
for jj = blockSize * (0:nrc(2)-1)
block = rand(blockSize*[1 1]);
if ~rowFirst
block = block';
end if
M(v + ii, v+jj) = block;
if rowFirst
imagesc(M);
else
imagesc(M');
end
axis equal tight xy
pause(0.1)
end
end
LAST TIME if you insist that the outer loop iterates over j and the inner loop over i, yet that in some instances j is the "faster moving" variable, you can do the following.
P = 120;
Q = 180;
M = zeros(P, Q); % not a square matrix
rowFirst = true; % a switch you can flip
blockSize = 15; % size of block
sz = floor(size(M)/blockSize); % number of iterations in j, i
nr = sz(1); nc = sz(2);
vv = 1:blockSize;
for jj = 0: (nc-1)
for ii = 0: (nr-1)
if(rowFirst)
kk = ii * blockSize;
ll = jj * blockSize;
else
nn = jj * nr + ii;
ll = mod(nn, nc);
kk = floor(nn / nc);
%ll = (nn - kk * nc);
fprintf(1, 'ii, jj, nn = [%d, %d, %d]: [kk, ll] = %d, %d\n', ii, jj, nn, kk, ll)
ll = ll * blockSize; kk = kk * blockSize;
% mod(nn, P);
end
M(kk+vv, ll+vv) = rand(blockSize*[1 1]);
imagesc(M);
axis tight equal xy;
pause(0.1);
end
end
Related
I want to determine the Steepest descent of the Rosenbruck function using Armijo steplength where x = [-1.2, 1]' (the initial column vector).
The problem is, that the code has been running for a long time. I think there will be an infinite loop created here. But I could not understand where the problem was.
Could anyone help me?
n=input('enter the number of variables n ');
% Armijo stepsize rule parameters
x = [-1.2 1]';
s = 10;
m = 0;
sigma = .1;
beta = .5;
obj=func(x);
g=grad(x);
k_max = 10^5;
k=0; % k = # iterations
nf=1; % nf = # function eval.
x_new = zeros([],1) ; % empty vector which can be filled if length is not known ;
[X,Y]=meshgrid(-2:0.5:2);
fx = 100*(X.^2 - Y).^2 + (X-1).^2;
contour(X, Y, fx, 20)
while (norm(g)>10^(-3)) && (k<k_max)
d = -g./abs(g); % steepest descent direction
s = 1;
newobj = func(x + beta.^m*s*d);
m = m+1;
if obj > newobj - (sigma*beta.^m*s*g'*d)
t = beta^m *s;
x = x + t*d;
m_new = m;
newobj = func(x + t*d);
nf = nf+1;
else
m = m+1;
end
obj=newobj;
g=grad(x);
k = k + 1;
x_new = [x_new, x];
end
% Output x and k
x_new, k, nf
fprintf('Optimal Solution x = [%f, %f]\n', x(1), x(2))
plot(x_new)
function y = func(x)
y = 100*(x(1)^2 - x(2))^2 + (x(1)-1)^2;
end
function y = grad(x)
y(1) = 100*(2*(x(1)^2-x(2))*2*x(1)) + 2*(x(1)-1);
end
I'm trying to reduce the processing time of bilinear interpolation of an image on a set of points. First I did a normal for loop. I can't use parfor since I'm already using it on the function that is calling the interp. I tried to vectorize the function, it works, but there is almost no reduce in processing time.
Any ideas of how can I improve the vectorized version?
Some results:
Edited - The results were varying a lot before. I don't know why, but now they seam consistent and the values don't change much.
I added the tmirt2D as #Dev-iL pointed it out. His code is a a lot faster (~3x) than mine, and he uses C++.
Interp 2D tester
Time for each point and speed up in '%' based on the reference time.
Array size: 10000. Repeat: 10. Loops: 20
Normal for loop interp: 145.6354 ns (reference time)
Vect interp (in bounds): 68.6679 ns (112.09%)
Vect interp (out boudns): 66.5793 ns (118.74%)
Vect interp nearest (in boudns): 28.2870 ns (414.85%)
Vect interp nearest (out boudns): 26.3854 ns (451.95%)
tmirt2D from File Exchange: 22.6089 ns (544.15%)
Matlab interp2 linear: 921.0408 ns (-84.19%)
Matlab interp2 nearest: 911.7492 ns (-84.03%)
Testing code:
clearvars; clc; close all;
mustCompareMatlab = 1;
tm1 = 0;
tm2 = 0;
tm3 = 0;
tm4 = 0;
tm5 = 0;
tm6 = 0;
tm7 = 0;
tmirt2D = 0;
baseLoopN = 10;
for j=1:baseLoopN
%% Create data
dataSize = [1200 1600];
data = rand(dataSize)*255;
N = 1e4;
X = rand(1,N)*dataSize(2);
Y = rand(1,N)*dataSize(1);
% Only inside bounds-1 coordinates
Xin = X(X<dataSize(2)-1);
Yin = Y(Y<dataSize(1)-1);
% make X and Y same size
Xin(end+1:length(X)) = ones(1,length(X)-length(Xin));
Yin(end+1:length(X)) = ones(1,length(X)-length(Yin));
% Make sure X and Y have outside bounds values
X(1) = dataSize(2) + 1;
Y(1) = dataSize(1) + 1;
loops = 20;
% Catch
interpData = Interp2D(data,X,Y);
tic
for i=1:loops
interpData = Interp2D(data,X,Y);
end
tm1 = tm1 + toc;
%% Only inside bounds coordinates
% Catch
interpData = Interp2DVect(data,Xin,Yin);
tic
for i=1:loops
interpData = Interp2DVect(data,Xin,Yin);
end
tm2 = tm2 + toc;
%% inside and outside bounds
% Catch
interpData = Interp2DVect(data,X,Y);
tic
for i=1:loops
interpDataInterp2DVect = Interp2DVect(data,X,Y);
end
tm3 = tm3 + toc;
%% inside bounds nearest
% Catch
interpData = Interp2DNearest(data,Xin,Yin);
tic
for i=1:loops
interpData = Interp2DNearest(data,Xin,Yin);
end
tm4 = tm4 + toc;
%% inside and outside bounds nearest
% Catch
interpData = Interp2DNearest(data,X,Y);
tic
for i=1:loops
interpData = Interp2DNearest(data,X,Y);
end
tm5 = tm5 + toc;
% mirt2D_mexinterp
% www.mathworks.com/matlabcentral/fileexchange/24183-2d-interpolation
interpData = mirt2D_mexinterp(data,X,Y);
tic
for i=1:loops
interpDataMirt2D = mirt2D_mexinterp(data,X,Y);
end
tmirt2D = tmirt2D + toc;
%% Matlab interp
if mustCompareMatlab
interpData = interp2(data,X,Y,'linear'); %#ok<*NASGU>
tic
for i=1:loops
interpData = interp2(data,Xin,Yin,'linear');
end
tm6 = tm6 + toc;
interpData = interp2(data,X,Y,'nearest');
tic
for i=1:loops
interpData = interp2(data,Xin,Yin,'nearest');
end
tm7 = tm7 + toc;
end
%%
end
A = interpDataInterp2DVect;
B = interpDataMirt2D;
C = A-B;
fprintf('Interp 2D tester\n');
fprintf('Array size: %d. Repeat: %d. Loops: %d\n',N,baseLoopN,loops);
tm1 = tm1*1e9/(baseLoopN*loops*N);
fprintf('Normal for loop interp: %.4f ns\n',tm1);
tm2 = tm2*1e9/(baseLoopN*loops*N);
fprintf('Vect interp (in bounds): %.4f ns (%.2f%%)\n',tm2,100*(tm1/tm2-1));
tm3 = tm3*1e9/(baseLoopN*loops*N);
fprintf('Vect interp (out boudns): %.4f ns (%.2f%%)\n',tm3,100*(tm1/tm3-1));
tm4 = tm4*1e9/(baseLoopN*loops*N);
fprintf('Vect interp nearest (in boudns): %.4f ns (%.2f%%)\n',tm4,100*(tm1/tm4-1));
tm5 = tm5*1e9/(baseLoopN*loops*N);
fprintf('Vect interp nearest (out boudns): %.4f ns (%.2f%%)\n',tm5,100*(tm1/tm5-1));
tmirt2D = tmirt2D*1e9/(baseLoopN*loops*N);
fprintf('tmirt2D from File Exchange: %.4f ns (%.2f%%)\n',tmirt2D,100*(tm1/tmirt2D-1));
if mustCompareMatlab
tm6 = tm6*1e9/(baseLoopN*loops*N);
fprintf('Matlab interp2 linear: %.4f ns (%.2f%%)\n',tm6,100*(tm1/tm6-1));
tm7 = tm7*1e9/(baseLoopN*loops*N);
fprintf('Matlab interp2 nearest: %.4f ns (%.2f%%)\n',tm7,100*(tm1/tm7-1));
end
Normal version:
function [interpData] = Interp2D(data,X,Y)
[sizY, sizX] = size(data);
interpData =zeros(1,length(X),'like',X);
for item=1:length(X),
valX=floor(X(item));
valY=floor(Y(item));
valYp1=valY+1;
valXp1=valX+1;
if (sizY < valYp1)||(sizX < valXp1)|| valX<=0 || valY<=0
interpData(item)=NaN;
else
Inten00=data(valY,valX);
Inten10=data(valY,valXp1);
Inten01=data(valYp1,valX);
Inten11=data(valYp1,valXp1);
px=(X(item))-valX;
py=(Y(item))-valY;
interpData(item)=((1-px)*Inten00+px*Inten10)*(1-py)+((1-px)*Inten01+px*Inten11)*py;
end
end
Vectorized version:
% Images borders are disconsidered due to simplicity
function [interpData,outBounds] = Interp2DVect(data,X,Y)
[sizeY, sizeX] = size(data);
fX = floor(X);
fY = floor(Y);
sizeOkFlag = ~((sizeY-1 < fY)|(sizeX-1 < fX)| fX <= 0 | fY <= 0);
sizeAllOk = min(sizeOkFlag) >= 1;
outBounds = ~sizeAllOk;
% If we have some invalid points, lets set them to NaN
if ~sizeAllOk
interpData = nan(1,length(X),'like',X);
% Prevent invalid data indexes
fX = fX(sizeOkFlag);
fY = fY(sizeOkFlag);
X = X(sizeOkFlag);
Y = Y(sizeOkFlag);
end
pX = X - fX;
pY = Y - fY;
% We need to get the linear indexes
% www.mathworks.com/company/newsletters/articles/matrix-indexing-in-matlab.html
%ids00 = sub2ind(dataSize, fY, fX);
% A fast replacement for sub2ind
% http://tipstrickshowtos.blogspot.com.br/2010/02/fast-replacement-for-sub2ind.html
%idsYX
ids00 = fY + (fX-1).*sizeY;
ids01 = fY + (fX).*sizeY;
ids10 = fY+1 + (fX-1).*sizeY;
ids11 = fY+1 + fX.*sizeY;
if sizeAllOk
interpData = ((1-pX).*data(ids00) + pX.*data(ids01)).*(1-pY) + ...
((1-pX).*data(ids10) + pX.*data(ids11)).*pY;
else
interpData(sizeOkFlag) = ((1-pX).*data(ids00) + pX.*data(ids01)).*(1-pY) + ...
((1-pX).*data(ids10) + pX.*data(ids11)).*pY;
if (size(X,1) > 1)
interpData = interpData';
end
end
Nearest version (just to compare)
function [interpData] = Interp2DNearest(data,X,Y)
[sizeY, sizeX] = size(data);
X = round(X);
Y = round(Y);
sizeOkFlag = ~((sizeY-1 < Y)|(sizeX-1 < X)| X <= 0 | Y <= 0);
% Slower if use this:
%sizeAllOk = min(sizeOkFlag) >= 1;
% if sizeAllOk
% ids = Y + (X-1).*sizeY;
% interpData = data(ids);
% else
interpData = nan(1,length(X),'like',X);
X = X(sizeOkFlag);
Y = Y(sizeOkFlag);
ids = Y + (X-1).*sizeY;
interpData(sizeOkFlag) = data(ids);
For my studies I had to write a PDE solver for the Poisson equation on a disc shaped domain using the finite difference method.
I already passed the Lab exercise. There is one issue in my code I couldn't fix. Function fun1 with the boundary value problem gun2 is somehow oscillating at the boundary. When I use fun2 everything seems fine...
Both functions use at the boundary gun2. What is the problem?
function z = fun1(x,y)
r = sqrt(x.^2+y.^2);
z = zeros(size(x));
if( r < 0.25)
z = -10^8*exp(1./(r.^2-1/16));
end
end
function z = fun2(x,y)
z = 100*sin(2*pi*x).*sin(2*pi*y);
end
function z = gun2(x,y)
z = x.^2+y.^2;
end
function [u,A] = poisson2(funame,guname,M)
if nargin < 3
M = 50;
end
%Mesh Grid Generation
h = 2/(M + 1);
x = -1:h:1;
y = -1:h:1;
[X,Y] = meshgrid(x,y);
CI = ((X.^2 +Y.^2) < 1);
%Boundary Elements
Sum= zeros(size(CI));
%Sum over the neighbours
for i = -1:1
Sum = Sum + circshift(CI,[i,0]) + circshift(CI,[0,i]) ;
end
%if sum of neighbours larger 3 -> inner note!
CI = (Sum > 3);
%else boundary
CB = (Sum < 3 & Sum ~= 0);
Sum= zeros(size(CI));
%Sum over the boundary neighbour nodes....
for i = -1:1
Sum = Sum + circshift(CB,[i,0]) + circshift(CB,[0,i]);
end
%If the sum is equal 2 -> Diagonal boundary
CB = CB + (Sum == 2 & CB == 0 & CI == 0);
%Converting X Y to polar coordinates
Phi = atan(Y./X);
%Converting Phi R back to cartesian coordinates, only at the boundarys
for j = 1:M+2
for i = 1:M+2
if (CB(i,j)~=0)
if j > (M+2)/2
sig = 1;
else
sig = -1;
end
X(i,j) = sig*1*cos(Phi(i,j));
Y(i,j) = sig*1*sin(Phi(i,j));
end
end
end
%Numberize the internal notes u1,u2,......,un
CI = CI.*reshape(cumsum(CI(:)),size(CI));
%Number of internal notes
Ni = nnz(CI);
f = zeros(Ni,1);
k = 1;
A = spalloc(Ni,Ni,5*Ni);
%Create matix A!
for j=2:M+1
for i =2:M+1
if(CI(i,j) ~= 0)
hN = h;hS = h; hW = h; hE = h;
f(k) = fun(X(i,j),Y(i,j));
if(CB(i+1,j) ~= 0)
hN = abs(1-sqrt(X(i,j)^2+Y(i,j)^2));
f(k) = f(k) + gun(X(i,j),Y(i+1,j))*2/(hN^2+hN*h);
A(k,CI(i-1,j)) = -2/(h^2+h*hN);
else
if(CB(i-1,j) ~= 0) %in negative y is a boundry
hS = abs(1-sqrt(X(i,j)^2+Y(i,j)^2));
f(k) = f(k) + gun(X(i,j),Y(i-1,j))*2/(hS^2+h*hS);
A(k,CI(i+1,j)) = -2/(h^2+h*hS);
else
A(k,CI(i-1,j)) = -1/h^2;
A(k,CI(i+1,j)) = -1/h^2;
end
end
if(CB(i,j+1) ~= 0)
hE = abs(1-sqrt(X(i,j)^2+Y(i,j)^2));
f(k) = f(k) + gun(X(i,j+1),Y(i,j))*2/(hE^2+hE*h);
A(k,CI(i,j-1)) = -2/(h^2+h*hE);
else
if(CB(i,j-1) ~= 0)
hW = abs(1-sqrt(X(i,j)^2+Y(i,j)^2));
f(k) = f(k) + gun(X(i,j-1),Y(i,j))*2/(hW^2+h*hW);
A(k,CI(i,j+1)) = -2/(h^2+h*hW);
else
A(k,CI(i,j-1)) = -1/h^2;
A(k,CI(i,j+1)) = -1/h^2;
end
end
A(k,k) = (2/(hE*hW)+2/(hN*hS));
k = k + 1;
end
end
end
%Solve linear system
u = A\f;
U = zeros(M+2,M+2);
p = 1;
%re-arange u
for j = 1:M+2
for i = 1:M+2
if ( CI(i,j) ~= 0)
U(i,j) = u(p);
p = p+1;
else
if ( CB(i,j) ~= 0)
U(i,j) = gun(X(i,j),Y(i,j));
else
U(i,j) = NaN;
end
end
end
end
surf(X,Y,U);
end
I'm keeping this answer short for now, but may extend when the question contains more info.
My first guess is that what you are seeing is just numerical errors. Looking at the scales of the two graphs, the peaks in the first graph are relatively small compared to the signal in the second graph. Maybe there is a similar issue in the second that is just not visible because the signal is much bigger. You could try to increase the number of nodes and observe what happens with the result.
You should always expect to see numerical errors in such simulations. It's only a matter of trying to get their magnitude as small as possible (or as small as needed).
I'm trying to write a Shidoku ( smaller and easier 4x4 variant of Sudoku) solver code in MATLAB.
I have found some soduko solver (9x9) but i could't revise them to be suitable for my problem. For example:
% Solving Sudoku Using Recursive Backtracking
function X = sudoku(X)
% SUDOKU Solve Sudoku using recursive backtracking.
% sudoku(X), expects a 9-by-9 array X.
% Fill in all “singletons”.
% C is a cell array of candidate vectors for each cell.
% s is the first cell, if any, with one candidate.
% e is the first cell, if any, with no candidates.
[C,s,e] = candidates(X);
while ~isempty(s) && isempty(e)
X(s) = C{s};
[C,s,e] = candidates(X);
end
% Return for impossible puzzles.
if ~isempty(e)
return
end
% Recursive backtracking.
if any(X(:) == 0)
Y = X;
z = find(X(:) == 0,1); % The first unfilled cell.
for r = [C{z}] % Iterate over candidates.
X = Y;
X(z) = r; % Insert a tentative value.
X = sudoku(X); % Recursive call.
if all(X(:) > 0) % Found a solution.
return
end
end
end
% ------------------------------
function [C,s,e] = candidates(X)
C = cell(9,9);
tri = #(k) 3*ceil(k/3-1) + (1:3);
for j = 1:9
for i = 1:9
if X(i,j)==0
z = 1:9;
z(nonzeros(X(i,:))) = 0;
z(nonzeros(X(:,j))) = 0;
z(nonzeros(X(tri(i),tri(j)))) = 0;
C{i,j} = nonzeros(z)';
end
end
end
L = cellfun(#length,C); % Number of candidates.
s = find(X==0 & L==1,1);
e = find(X==0 & L==0,1);
end % candidates
end % sudoku
Any help will be helpful.
Just reduce the problem dimensionality from 3 to 2 (I know now that it is said "9x9" instead of "3x3", but the important dimensional number for the puzzle is N=3):
% SHIDOKU Solve Shidoku using recursive backtracking.
% shidoku(X), expects a 4-by-4 array X.
function X = shidoku(X)
[C,s,e] = candidates(X);
while ~isempty(s) && isempty(e)
X(s) = C{s};
[C,s,e] = candidates(X);
end;
if ~isempty(e)
return
end;
if any(X(:) == 0)
Y = X;
z = find(X(:) == 0,1);
for r = [C{z}]
X = Y;
X(z) = r;
X = shidoku(X);
if all(X(:) > 0)
return;
end;
end;
end;
% ------------------------------
function [C,s,e] = candidates(X)
C = cell(4,4);
bi = #(k) 2*ceil(k/2-1) + (1:2);
for j = 1:4
for i = 1:4
if X(i,j)==0
z = 1:4;
z(nonzeros(X(i,:))) = 0;
z(nonzeros(X(:,j))) = 0;
z(nonzeros(X(bi(i),bi(j)))) = 0;
C{i,j} = transpose(nonzeros(z));
end;
end;
end;
L = cellfun(#length,C); % Number of candidates.
s = find(X==0 & L==1,1);
e = find(X==0 & L==0,1);
end % candidates
end % shidoku
I am trying to implement local thresholding in MATLAB 7.7. This is what my original image looks like:
As seen the the word Test is covered in black. This image is a PNG image having dimensions 919x551. I want to apply local thresholding to this image so that I can get the word Test to be visible clearly.
I have implemented the following code that works by dividing the entire image into sub images of 60*60 blocks.
However, when I am doing so, I am not getting the desired output.
My code:
clc;
clear all;
close all;
im = imread('C:\samples\test100.png');
subplot(3,3,1);
imshow(im);
title('original image');
im = rgb2gray(im);
im = double(im);
subplot(3,3,2);
imshow(im);
title('gray scale image');
[row col] = size(im);
max_im = max(max(im));
h = zeros(1,max_im+1);
!1st block
for n = 1:1:60
for m = 1:1:60
a(n,m) = im(n,m);
end
end
a = a+1;
for n = 1:1:60
for m = 1:1:60
t = a(n,m);
h(t) = h(t)+1;
end
end
subplot(3,3,3);
bar(h)
[X,Y] = ginput(1);
for n = 1:1:60
for m = 1:1:60
if a(n,m)<X
a(n,m) = 0;
else
a(n,m) = 255;
end
end
end
subplot(3,3,4);
imshow(uint8(a))
title('1st block image');
!2nd block
for n = 1:1:60
for m = 61:1:60
b(n,m-60) = im(n,m)
end
end
b = b+1;
for n = 1:1:60
for m = 1:1:60
t = b(n,m);
h(t) = h(t)+1;
end
end
figure(2)
bar(h)
[X,Y] = ginput(1);
for n = 1:1:60
if b(n,m)<X
b(n,m) = 0;
else
b(n,m) = 255;
end
end
imshow(uint8(b))
!3rd block
for n = 61:1:120
for m = 1:1:60
c(n-60,m) = im(n,m);
end
end
c = c+1;
for n = 1:1:60
for m = 1:1:60
t = c(n,m);
h(t) = h(t)+1;
end
end
figure(3)
bar(h)
[X,Y] = ginput(1);
for n = 1:1:60
for m = 1:1:60
if c(n,m)< X
c(n,m) = 0;
else
c(n,m) = 255;
end
end
end
imshow(uint8(c))
!final block
for n = 1:1:row
for m = 61:1:col
d(n-60,m-60) = im(n,m);
end
end
d = d+1;
for n = 1:1:60
for m = 1:1:60
t = d(n,m);
h(t) = h(t)+1;
end
end
figure(4);
bar(h);
[X,Y] = ginput(1);
for n = 1:1:60
for m = 1:1:60
if d(n,m)<X
d(n,m) = 0;
else
d(n,m) = 255;
end
end
end
imshow(uint8(d))
s = [a b;c d];
figure(5);
imshow(uint(s))
When I try to run the entire code I get an error as:
??? Undefined function or method 'local' for input arguments of type 'char'
However, when I run only the code for the 1st block I get the following output.
How will I get the word Test visible by creating sub-images and then merging them together?
You can scan the greyscale image horizontally and then find the position of non-zero (or above the threshold) values and set that interval to be filled with white (256 or 1 if using im2double).
for j=1:551
row = im(:,j)
test = 0;
im2=zeros(size(im))
i=0;
%Left black area
while (test == 0 && i<919)
im2(i,j)=0;
if row(i)>threshold
test=1;
end;
i=i+1;
end;
%White inner area
while (test == 1 && i<919)
im2(i,j)=1
if row(i)>threshold
test=0;
end;
i=i+1;
end;
%Left black area
while (i<919)
im2(i,j)=0;
i=i+1;
end;
This doesn't work with letters that have an empty area (such as 'p'), but you can modify the code a little to do that.