how to convert a 3x3 matrix to an RGB image in matlab - image

suppose that I have the following code:
clc
clear
band1 = imread('C:\Users\sepideh\Desktop\DrAkhundzadeh\Bands\band1.tif');
band2 = imread('C:\Users\sepideh\Desktop\DrAkhundzadeh\Bands\band2.tif');
band3 = imread('C:\Users\sepideh\Desktop\DrAkhundzadeh\Bands\band3.tif');
band4 = imread('C:\Users\sepideh\Desktop\DrAkhundzadeh\Bands\band4.tif');
band5 = imread('C:\Users\sepideh\Desktop\DrAkhundzadeh\Bands\band5.tif');
band7 = imread('C:\Users\sepideh\Desktop\DrAkhundzadeh\Bands\band7.tif');
Vegetation = band4-band3;
Oxide = band3-band1;
Hydroxyl = band5-band7;
%Normalize
NormalizedVegetation = ( Vegetation - min(min(Vegetation)))*255/(max(max(Vegetation)) - min(min(Vegetation)));
NormalizedOxide = ( Oxide - min(min(Oxide)))*255/(max(max(Oxide)) - min(min(Oxide)));
NormalizedHydroxyl = ( Hydroxyl - min(min(Hydroxyl)))*255/(max(max(Hydroxyl)) - min(min(Hydroxyl)));
FalseColor(:,:,1) = NormalizedVegetation;
FalseColor(:,:,2) = NormalizedOxide;
FalseColor(:,:,3) = NormalizedHydroxyl;
RGBIMAG = uint8(FalseColor);
imshow(RGBIMAG);
my problem is with the line:
RGBIMAG = uint8(FalseColor);
which causes all the image to get darked. How can I tell matlab that each level of the 3 dimensional matrix are different band of an RGB image without changing its elements.

For converting to uint8, you must use:
RGBIMAG = im2uint8(FalseColor);
That function receives ur double array( values btw 0-1 ) and converts them to RGB values in the range (0, 255).

Related

Matlab : Create Rectangular Box with name

Currently, I try to draw a rectangular box around a white object with a label indicating its size.
I want create 4 categories of sizes:
Don't have
Small
Medium
Big
I don't have clue how to create this.
use insertObjectAnnotation:
% generate image
bw = zeros(1000);
[xg,yg] = meshgrid(1:1000);
rads = 10:20:100;
for ii = 1:length(rads)
r = rads(ii);
c = randi([1+r,1000-r],[1,2]);
bw = bw | ( ((xg - c(1)).^2 + (yg - c(2)).^2) < r^2);
end
% extract region properties
props = regionprops(bw,'Area','BoundingBox');
% add labels
sizes = [0,2000,6000,10000];
labels = {'tiny','small','medium','large'};
colors = autumn(numel(labels));
bw = double(bw);
for ii = 1:numel(props)
labelidx = find(props(ii).Area > sizes,1,'last');
bw = insertObjectAnnotation(bw,'rectangle',...
props(ii).BoundingBox,labels{labelidx},...
'Color',colors(labelidx,:),'FontSize',32);
end
imshow(bw);
EDIT: applying this to the OP's image:

Resize a polygon image in matlab

I have two polygon images defined by 25 control points. I want to replace one polygon by another one in matlab. Below is an example of TC and BP.
I have added the code. I am not happy with the output texture in the replaced area. Also, I found the that if the polygon shape of the second image is smaller than the first image polygon shape then the output looks very bad.
clc;clear all;close all
im_original = imread('tc.jpg');
im_original=im2double(im_original);
%% ROI (X,Y) coordinates, variable name (pt_original)
load('tc.mat');
im_morphed = imread('bp.jpg');
img_morphed=im2double(im_morphed);
%% ROI (X,Y) coordinates, variable name (pt_morphed)
load('bp.mat');
%% Replace Face
[img_proc,mask] = defineRegion(im_original,pt_original);
img_morphed_proc = histeq_rgb(img_morphed, im_original, mask, mask);
sigma = 5;
se = strel('square',sigma);
mask = imerode(mask,se);
w = fspecial('gaussian',[50 50],sigma);
mask = imfilter(double(mask),w);
img_result = bsxfun(#times,double(img_morphed_proc),double(mask)) + bsxfun(#times,double(im_original),double(1-mask));
imshow(img_result)
function [img_proc,mask] = defineRegion(img, landmark)
sz = size(img);
k =convhull(landmark(:,2),landmark(:,1));
[YY,XX] = meshgrid(1:sz(1),1:sz(2));
in = inpolygon(XX(:),YY(:),landmark(k,1),landmark(k,2));
mask = reshape(in,[sz(2),sz(1)])';
img_proc = bsxfun(#times,im2double(img),double(mask));
end
function img_proc = histeq_rgb(img_src, img_dest, mask_src, mask_dest)
img_proc = img_src;
for i = 1 : 3
tmp_src = img_src(:,:,i);
tmp_src = tmp_src(mask_src);
tmp_dest = img_dest(:,:,i);
tmp_dest = tmp_dest(mask_dest);
t = histeq(tmp_src,imhist(tmp_dest));
tmp_proc = img_proc(:,:,i);
tmp_proc(mask_src) = t;
img_proc(:,:,i) = tmp_proc;
end
end
Output Image

matlab 3d projection image

I'm doing a image 3D projection, but when I use the iwarp function the result is a multidimensional matrix, I'm using:
color1 = imread('color1.jpg') % 480x640x3 image RBG
%4X4 projection matrix
Mx = makehgtform('xrotate',-0.01970);
My = makehgtform('yrotate',0.01729);
Mz = makehgtform('zrotate',-0.00717);
M = Mx*My*Mz;
M(1,4) = -28.54007;
M(2,4) = -2.00470;
M(3,4) = 4.37353;
T = affine3d(M);
%Do transform
Color_Rectified = imwarp(color1,T); %485X644x24
At the end, the Color_Rectified size is 485X644x24, the idea is to get the image rotated/translated in X,Y,Z and RGB, how to do this?

Determine a regions average in MATLAB

I need some help with RGB capture in a image.
I am using impixel to manualy get RGB from a picture, but i would like to create a grid of let's say 20x20 px boxes where it will automatically tell me for each box a RGB value. So in a picture lets say i have 20 boxes it will tell me 20 RGB values. Yeah an if there is 20% or more of white space that it ignores that rgb box.
Can you point me to some links or give me a general idea how to do this.
Best regards
P.S. image is just a .jpg, the background is white an in the middle there is an item.
UPDATE
This is my code for collecting RGB using impixel
px=impixel(img);
st = num2cell(px,1);
zstup = cellfun(#sum,st);
zred = size(px,1);
rez = bsxfun(#rdivide,zstup,zred);
trez=round(rez);
What I want to do is :
http://imageshack.us/photo/my-images/696/exsample.jpg/
So every box like A1, A2, and so on will return RGB value like trez in my code.
So in my code i save my trez data in a table and it is like in excell lets say 220 | 23 | 34, now if i do that to another fruit i will have
220 | 23 | 34
123 | 212| 78
and so on...
Returning to automatization, A7 and A 15 would not be good RGB canditades because they have more then 50% white area so everything that has 20% white will be ignored.
So A31 is good and the RGB value needs to be saved.
So all in all here i would have my be 6 RGB values that would have to be automatically saved like the above example.
I know how to save to table i just need help for the gathering rgb values in every box.
Depending on your exact needs I see two solutions:
Downscale the image using impyramid(img, 'reduce'). This gives you a smaller image consisting of average values of the original image. Then do what you did before to access single pixels. Repeat as often as necessary to get 2x2, 4x4, 8x8 or larger "boxes".
Or you could use define a box (or arbitrary shape) as a matrix of ones and zeros and use the regionprops function in order to get information about the images content depending on the fields containing ones:
roi = zeros(size(img))
roi(1:10,1:10) = 1;
r = regionprops(roi, img, 'MeanIntensity')
average = r.MeanIntensity
This is my complete code for automatic color grabing from pictures in folder. So the program asks you to chose a folder and after that you get a table full of information about color and roundess. I am using this code to get color from fruits that have white background . It does everything by itself. Hope it helps someone.
clear all;
clc;
uiwait(msgbox('Chose the folder where your pictures are kept. Click OK to continue..'));
% Opening the folder
folder = uigetdir(pwd);
filePattern = fullfile(folder, '*.jpg');
jpegFiles = dir(filePattern);
for k = 1:length(jpegFiles)
baseFileName = jpegFiles(k).name;
fullFileName = fullfile(folder, baseFileName);
[pathstr, name, ext] = fileparts(fullFileName);
naziv_voca=name;
%Taking RGB color
slika = imread(fullFileName);
[redovi stupci RGBboje] = size(slika);
red_ink = floor(redovi/10);
stup_ink = floor(stupci/10);
r = 1;
c = 1;
for stupac = 1 : stup_ink : stupci
for red = 1 : red_ink : redovi
red1 = red;
red2 = red1 + red_ink;
stupac1 = stupac;
stupac2 = stupac1 + stup_ink;
red2 = min(red2, redovi);
stupac2 = min(stupac2, stupci);
crveniS = slika(red1:red2, stupac1:stupac2, 1);
zeleniS = slika(red1:red2, stupac1:stupac2, 2);
plaviS = slika(red1:red2, stupac1:stupac2, 3);
crvena(r,c) = mean2(crveniS);
zelena(r,c) = mean2(zeleniS);
plava(r,c) = mean2(plaviS);
r = r + 1;
if r >redovi
r = 1;
end
end
c = c + 1;
if c >1
c = 1;
end
end
RGB=[crvena,zelena,plava];
bijela=[255 255 255];
tolerancija = 50;
rez = RGB((abs(RGB(:,1)-bijela(1)) > tolerancija) | (abs(RGB(:,2)-bijela(2)) > tolerancija),:);
trez=round(rez);
%Taking shape
pic = rgb2gray(slika);
threshold = graythresh(pic);
bw = im2bw(pic,threshold);
fbw = ones(size(bw))-imfill(ones(size(bw))-bw);
invImg = ~fbw;
f = bwlabel(invImg);
S = regionprops(f,'Area','Perimeter','centroid');
Thr=100;
S=S([S.Area]>Thr);
score = (min(sqrt([S.Area]),[S.Perimeter]/4)./(max(sqrt([S.Area]), [S.Perimeter]/4))).^2;
score=max(score);
%Inserting data into table and creating data
if exist('tablica.mat','file')
vel=size(trez,1);
for z=1:vel
s=load('tablica');
olddata=s.data;
temp=trez(z,:);
dataCell= [naziv_voca,num2cell(temp),num2cell(score)];
data=[olddata;dataCell];
save('tablica.mat','-append','data');
end
else
stupac_rgb = num2cell(trez,1);
zstupac = cellfun(#sum,stupac_rgb);
zred = size(trez,1);
rez = bsxfun(#rdivide,zstupac,zred);
trez=round(rez);
data= [naziv_voca,num2cell(trez),num2cell(score)];
save('tablica','data')
end
end
uiwait(msgbox('Your information is saved'));

Matlab - displaying a background image

I'm trying to find the median values for the R,G & B channels of each pixel for each 10th image in a set of 100, to find the background image. My values all seem correct but when i try to display the background at the end of my code it's always white, please help
%// list all the files in some folder
folder = '~/V&R/1/';
filelist = dir(folder);
images = zeros(480,640,3,100);
% images = [];
%// the first two in filelist are . and ..
count = 1;
for i=3:size(filelist,1)
if filelist(i).isdir ~= true
fname = filelist(i).name;
%// if file extension is jpg
if strcmp( fname(size(fname,2)-3:size(fname,2)) ,'.jpg' ) == 1
tmp = imread([folder fname]);
images(:,:,:,count) = tmp;
count = count +1;
end
end
end
background = zeros(480,640,3);
for j=1:480
for i=1:640
tmpR = zeros(1,10);
tmpG = zeros(1,10);
tmpB = zeros(1,10);
for k=1:10
tmpR(k) = images(j,i,1,k*10);
tmpG(k) = images(j,i,2,k*10);
tmpB(k) = images(j,i,3,k*10);
end
background(j,i,1) = floor(median(tmpR));
background(j,i,2) = floor(median(tmpG));
background(j,i,3) = floor(median(tmpB));
end
end
imshow(background)
thanks
The first step is to vectorize your code. Instead of the following block of code:
background = zeros(480,640,3);
for j=1:480
for i=1:640
tmpR = zeros(1,10);
tmpG = zeros(1,10);
tmpB = zeros(1,10);
for k=1:10
tmpR(k) = images(j,i,1,k*10);
tmpG(k) = images(j,i,2,k*10);
tmpB(k) = images(j,i,3,k*10);
end
background(j,i,1) = floor(median(tmpR));
background(j,i,2) = floor(median(tmpG));
background(j,i,3) = floor(median(tmpB));
end
end
write:
subimages = images(:, :, :, 1:10:end);
background = median(subimages, 4);
now as said before, use imshow with the [] option to show your image:
imshow(background, []);
if you still see a white image, then it's possible that you are dealing with a matrix of double values that are not between [0, 1]. Images in Matlab are usually of class double or single with values between 0 and 1, or of class uint8 or uint16 with values between 0, 255 or 0, 65535 respectively. If your values are between 0 and 255 but class(subimages) returns double or single, do the following before using imshow():
subimages = uint8(subimages);
Try
imshow(background,[])
When using imshow, MATLAB needs to set a display range. For single or double grayscale images, the default display range is [0 1]. This means that any value larger than 1 will be represented as white. You can fix this by setting your own display range manually, say
imshow(background,[0 100],
or you can let MATLAB calculate a new display range by doing
imshow(background,[])
which is the same as
imshow(background,[min(background(:)) max(background(:))])
You can rewrite your code as:
%# get filenames of all JPG images in some folder
folder = '~/V&R/1/';
filelist = dir( fullfile(folder,'*.jpg') );
filelist = strcat(folder, filesep, {filelist.name});
%# read files, and store as 'double' images in a 4D matrix
images = zeros(480,640,3, numel(filelist), 'double');
for i=1:numel(filelist)
images(:,:,:,i) = im2double( imread(filelist{i}) );
end
%# estimate background using median
subimages = images(:,:,:,1:10:end);
background = median(subimages, 4);
imshow(background)

Resources