I am trying to execute local binary pattern in MATLAB using the image processing toolbox. When i execute I can't get a LBP image and LBP histogram.
clear all;
close all;
clc;
I=imread('test.png');
figure,imshow(I)
%% Crop
I2 = imcrop(I);
figure, imshow(I2)
w=size(I2,1);
h=size(I2,2);
%% LBP
scale = 2.^[7 6 5; 0 -inf 4; 1 2 3];
for i=2:w-1
for j=2:h-1
J0=I2(i,j);
I3(i-1,j-1)=I2(i-1,j-1)>J0;
I3(i-1,j)=I2(i-1,j)>J0;
I3(i-1,j+1)=I2(i-1,j+1)>J0;
I3(i,j+1)=I2(i,j+1)>J0;
I3(i+1,j+1)=I2(i+1,j+1)>J0;
I3(i+1,j)=I2(i+1,j)>J0;
I3(i+1,j-1)=I2(i+1,j-1)>J0;
I3(i,j-1)=I2(i,j-1)>J0;
LBP(i,j)=I3(i-1,j-1)*2^7+I3(i-1,j)*2^6+I3(i-1,j+1)*2^5+I3(i,j+1)*2^4+I3(i+1,j+1)*2^3+I3(i+1,j)*2^2+I3(i+1,j-1)*2^1+I3(i,j-1)*2^0;
end
end
figure,imshow(LBP)
figure,imhist(LBP)
what is the issue.i am supposed to get numbers from 0 to 255.
I3(i-1,j-1)=I2(i-1,j-1)>J0; creates a logical as output. If you don't go and cast this to something else, you're image will only be zeros and ones.
The easiest way is to initialize I3 outside the loop, i.e. have I3=I2; before you start looping. This way, all your assignments inside the loop get converted to whatever class I2 was.
use :
figure,imshow(uint8(LBP));
Its becuase LBP image is in DOUBLE, you need to cast it.
Related
I want to rectify an image with perspectival distorsion. I have points of the corners and I have also have an algorithm that perfoms what I need but it executes really slow. It has 'imtransform' and 'maketform' functions which matlab has faster functions for these actions. So I tried to replace them but I couldn't make it right. Any helps will be appreciated.
Here is the Images to make this question clearer:
Input Image with known Coordinates(x,y):
and Desired Output:
This process executed with the interval of 2 seconds, I need to replace this process via new matlab functions but I couldn't make it.
Old algorihm was:
%X has the clockwise X coordinates %Y has the clockwise Y coordinates
A=zeros(8,8);
A(1,:)=[X(1),Y(1),1,0,0,0,-1*X(1)*x(1),-1*Y(1)*x(1)];
A(2,:)=[0,0,0,X(1),Y(1),1,-1*X(1)*y(1),-1*Y(1)*y(1)];
A(3,:)=[X(2),Y(2),1,0,0,0,-1*X(2)*x(2),-1*Y(2)*x(2)];
A(4,:)=[0,0,0,X(2),Y(2),1,-1*X(2)*y(2),-1*Y(2)*y(2)];
A(5,:)=[X(3),Y(3),1,0,0,0,-1*X(3)*x(3),-1*Y(3)*x(3)];
A(6,:)=[0,0,0,X(3),Y(3),1,-1*X(3)*y(3),-1*Y(3)*y(3)];
A(7,:)=[X(4),Y(4),1,0,0,0,-1*X(4)*x(4),-1*Y(4)*x(4)];
A(8,:)=[0,0,0,X(4),Y(4),1,-1*X(4)*y(4),-1*Y(4)*y(4)];
v=[x(1);y(1);x(2);y(2);x(3);y(3);x(4);y(4)];
u=A\v;
%transfer fonksiyonumuz
U=reshape([u;1],3,3)';
w=U*[X';Y';ones(1,4)];
w=w./(ones(3,1)*w(3,:));
T=maketform('projective',U');
%transform uygulayıp resmi düzleştiriyoruz
P2=imtransform(I,T,'XData',[1 n],'YData',[1 m]);
if it helps, here is how I generated "A" matrix and U matrix:
Out Link
using the builtin MATLAB functions (fitgeotrans, imref2d, and imwarp) the following code runs in 0.06 seconds on my laptop:
% read the image
im = imread('paper.jpg');
tic
% set the moving points := the original image control points
x = [1380;2183;1282;422];
y = [727;1166;2351;1678];
movingPoints = [x,y];
% set the fixed points := the desired image control points
xfix = [1;1000;1000;1];
yfix = [1;1;1000;1000];
fixedPoints = [xfix,yfix];
% generate geometric transform
tform = fitgeotrans(movingPoints,fixedPoints,'projective');
% generate reference object (full desired image size)
R = imref2d([1000 1000]);
% warp image
outputImage = imwarp(im,tform,'OutputView',R);
toc
% show image
imshow(outputImage);
I have to save the image. But when I try and keep the dimensions same, pixel values change. Is there any way to keep both intact.
C=imread('download.jpg');
C=rgb2gray(C);
%convert to DCT
[r1 c1]=size(C);
CDCT=floor(dct2(C));
dct=floor(dct2(C));
[r c]= size(dCipherText);
bye=c; %lenght of message bits
for i=r1:r1
for j=c1:-1:c1-28
.....%some operation on CDCT
end
end
imshow(idct2(CDCT),[0 255])
i=idct2(CDCT);
set(gcf,'PaperUnits','inches','PaperPosition',[0 0 c1 r1])
print -djpeg fa.jpg -r1
end
Don't use print to save the picture.
Use:
imwrite(i,'downdload_dct.jpg')
print will use the paper dimensions etc defined on your figure, rather than the image data itself. imwrite uses the data in i. You don't need imshow if you just want to re-save the image.
--
Update - sorry I see now that when you mean 'scaling', you don't mean the scaling of the picture but of the pixel values, and converting back from scalars to a colour. imshow only "scales" things on the screen, not in your actual data. So you will need to do that manually / numerically. Something like this would work, assuming i is real.
% ensure i ranges from 1 to 255
i = 1 + 254*(i-min(i(:))*(max(i(:))-min(i(:))) ;
% convert indices to RGB colour values (m x n x 3 array)
i = ind2rgb(i,jet(256));
not tested!
% Image Arithmetic Operations
% Image addition is done between two similar size of image, so image resize
% function is used to make size of both image same.
% I=I1+I2
clc
close all
I1=imread('test.jpg');
I2=imread('test_1.jpg');
subplot(2,2,1);imshow(I1);title('Original image I1');
subplot(2,2,2);imshow(I2);title('Original image I2');
I=I1+I2; % Addition of two images
subplot(2,2,3);imshow(I);title('Addition of image I1+I2');
I=I1-I2; % Subtraction of two images
subplot(2,2,4);imshow(I);title('Subtraction of image I1-I2');
figure;
subplot(2,2,1);imshow(I1);title('Original image I1');
I=I1+50;
subplot(2,2,2);imshow(I);title('Bright image I');
I=I1-100;
subplot(2,2,3);imshow(I);title('Dark image I');
M=imread('key.png');
M=im2bw(M); % Converts into binary image having 0s and 1s
I=uint8(I1).*uint8(M); % Type casting before multiplication
subplot(2,2,4);imshow(I);title('Masked Image I');
%clear all;
[filename,pathname]=uigetfile({'*.bmp;*.jpg;*.gif','Choose Image File'});
myimage=imread(filename);
if(size(myimage,3)==3)
myimage=rgb2gray(myimage);
end
[Rows,Cols]=size(myimage);
newimage=zeros(Rows,Cols);
k=1;
while k<5
for i=1:Rows
for j=1:Cols
if k==1
newimage(i,j)=myimage(i,j)-100;
end
if k==2
newimage(i,j)=myimage(i,j)-50;
end
if k==3
newimage(i,j)=myimage(i,j)+50;
end
if k==4
newimage(i,j)=myimage(i,j)+50;
end
end
end
subplot(2,2,k);imshow(newimage,[]);
k=k+1;
end
% calculate mean value
[Rows,Cols]=size(myimage);
newimage=zeros(Rows,Cols);
total=0;
for i=1:Rows
for j=1:Cols
total=total+myimage(i,j);
end
end
average=total/(Rows*Cols);
I am in big trouble because this error is not resolved and i am new to matlab coding so please help me and your solution is appreciated to me in future.
I faced an error mentioned below :
??? Error using ==> times Matrix dimensions must agree.
Error in ==> DIP_3 at 23 I=uint8(I1).*uint8(M); % Type casting before
multiplication
Assuming that the three images you are working with (test.jpg, test_1.jpg and test.png) are of the same size, the problem arises when you call the im2bw function
M=im2bw(M);
The input matrix M is a 3D matrix (eg. 100x100x3) while the output matrix is only a 2D matrix (100x100).
The error is generated because you multiply matrix I1 (which is also a 3D matrix) by a 2D matrix.
I=uint8(I1).*uint8(M);
You have therefore to make the matrix M a 3D matrix.
If you want to apply the same scaling factor on matrix I1 you can do something like:
M=imread('key.png');
M0=im2bw(M); % Converts into binary image having 0s and 1s
M(:,:,2)=M0;
M(:,:,3)=M0;
Otherwise, you have to define, somehow M(:,:,2) and M(:,:,3)
Hope this helps.
I have a gray image of size 400 x 600 . And i want to select randomly from this image, a patch of size 50 x 50.
By the way, i tried to write a code for this, and it worked fine. But according to my code below, there is another solution ? In other words, is there another code which can be more sexy than my own code ?
clear all;
close all;
clc;
image=imread('my_image.jpg');
image_gray=rgb2gray(image);
[n m]= size(image_gray); % 400 x600
L=50;
x=round(rand(1)*n); % generate a random integer between 1 and 400
y=round(rand(1)*m); % generate a random integer between 1 and 600
%verify if x is > than 400-50 , because if x is equal to 380 for example, so x+50 become %equal to 430, it exceeds the matrix dimension of image...
if(x<=n-L)
a=x:x+(L-1);
else
a=x-(L-1):x;
end
if(y<=m-L)
b=y:y+(L-1);
else
b=y-(L-1):y;
end
crop=image_gray(a,b);
figure(1);
imshow(crop);
This is as "sexy" as it gets. Satisfaction guaranteed ;-)
% Data
img=imread('my_image.jpg');
image_gray=rgb2gray(img);
[n m]= size(image_gray);
L = 50;
% Crop
crop = image_gray(randi(n-L+1)+(0:L-1),randi(m-L+1)+(0:L-1));
If using a Matlab version that doesn't support randi, substitute last line by
crop = image_gray(ceil(rand*(n-L+1))+(0:L-1),ceil(rand*(m-L+1))+(0:L-1));
Comments to your code:
You shouldn't use image as a variable name. It overrides a function.
You should change round(rand(1)*n) to ceil(rand(1)*n). Or use randi(n).
Instead of randi(n), use randi(n-L+1). That way you avoid the ifs.
For anyone struggling to get this code to work for RGB images, when you compute the size you'll want to add an extra variable for the third dimension. i.e.
% Data
img=imread('my_image.jpg');
% Not making anything gray anymore
[n, m, ~]= size(img);
L = 50;
% Crop - add a : in order to get 3 or more dimensions at the end
crop = img(randi(n-L+1)+(0:L-1),randi(m-L+1)+(0:L-1), :);
Super simple but not necessarily obvious at first.
When I tried to calculate the variance of each of the block within an image, the same way in which I have tried to calculate mean, it throws an error like:
??? Error using ==> var at 56
First argument must be single or double.
Error in ==> #(x)var(x(:))
Error in ==> assignemt at 19
varValues = cellfun(#(x) var(x(:)),b);
Could anyone help in this regard?
The code I have written is
clc;
close all;
d=8;
a=imread('lena.jpg');
figure();
imshow(a);
b=mat2cell(a,[16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16[16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16]);
[m,n]=size(b);
[m,n]=size(a);
%calculate mean for host image
% for i=1:m
% for j=1:n
% meanValues = cellfun(#(x) mean(x(:)),b);
% end
% end
% calculate variance for host image
for i=1:m
for j=1:n
varValues = cellfun(#(x) var(x(:)),b);
end
end
You are using x(:) which is a cell. Try using [x{:}]
Your code does not run, the mat2cell-line contains two [ and none ] so I did not try it out.
Your image a is of type uint8 and therefore var is failing. Try converting the image to double either by im2double or double(a)/255.
BTW, why don't you use blockproc, nlfilt2 or similar functions?