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)
Related
I am trying to train an image translation model with TensorFlow, the dataset consists of two equal length list of images, how do I apply a map both of them so they receive the same augmentations.
I have tried to create a variable to keep track of which iteration it is, as well as using a seeded random number.
def load_and_preprocess_color(path):
image = tf.read_file(path)
image = tf.image.decode_png(image, channels=3)
image = tf.image.resize(image, [224, 224])
image = tf.image.random_flip_left_right(image)
image /= 255.0 # normalize to [0,1] range
return image
def load_and_preprocess_gray(path):
image = tf.read_file(path)
image = tf.image.decode_png(image, channels=1)
image = tf.image.resize(image, [224, 224])
image = tf.image.random_flip_left_right(image)
image /= 255.0 # normalize to [0,1] range
return image
input_data_root = pathlib.Path('Images/Gray/') output_data_root =
pathlib.Path('Images/Color/')
input_image_paths = [str(item) for item in input_data_root.iterdir()]
output_image_paths = [str(item) for item in
output_data_root.iterdir()] image_count = len(input_image_paths)
input_path_ds = tf.data.Dataset.from_tensor_slices(input_image_paths)
output_path_ds =
tf.data.Dataset.from_tensor_slices(output_image_paths)
input_ds =
input_path_ds.map(load_and_preprocess_gray,num_parallel_calls=AUTOTUNE)
output_ds =
output_path_ds.map(load_and_preprocess_color,num_parallel_calls=AUTOTUNE`
I expect two pieces of data at the same position to be either flipped of not flipped, but its flipped state to be the same as the other
How can I scale the colorbar axis of a false color image?
I read this post,and copied the code but it seems not to work correctly:
MATLAB Colorbar - Same colors, scaled values
Please see the two images below. In the first (without the scaling) the coloraxis goes
[1 2 3 4 5 6]*10^4
In the second image, it goes
[0.005 0.01 0.015 0.02 0.025]
The correct scaling (with C = 100000) would be
[0.1 0.2 0.3 0.4 0.5 0.6]
Without scaling
Wrong scaling
I want that the coloraxis is scaled by 1/C and I can freely choose C, so that when the pixel value = 10^4 and C=10^6 the scale should show 10^-2.
The reason why I multiply my image first by C is to get more decimals places, because all values below 1 will be displayed as zero without the C scaling.
When I run the code I get yticks as a workspace variable with the following values:
[500 1000 1500 2000 2500]
My code:
RGB = imread('IMG_0043.tif');% Read Image
info = imfinfo('IMG_0043.CR2'); % get Metadata
C = 1000000; % Constant to adjust image
x = info.DigitalCamera; % get EXIF
t = getfield(x, 'ExposureTime');% save ExposureTime
f = getfield(x, 'FNumber'); % save FNumber
S = getfield(x, 'ISOSpeedRatings');% save ISOSpeedRatings
date = getfield(x,'DateTimeOriginal');
I = rgb2gray(RGB); % convert Image to greyscale
K = 480; % Kamerakonstante(muss experimentel eavaluiert werden)
% N_s = K*(t*S)/power(f,2))*L
L = power(f,2)/(K*t*S)*C; %
J = immultiply(I,L); % multiply each value with constant , so the Image is Calibrated to cd/m^2
hFig = figure('Name','False Color Luminance Map', 'ToolBar','none','MenuBar','none');
% Create/initialize default colormap of jet.
cmap = jet(16); % or 256, 64, 32 or whatever.
% Now make lowest values show up as black.
cmap(1,:) = 0;
% Now make highest values show up as white.
cmap(end,:) = 1;
imshow(J,'Colormap',cmap) % show Image in false color
colorbar % add colorbar
h = colorbar; % define colorbar as variable
y_Scl = (1/C);
yticks = get(gca,'YTick');
set(h,'YTickLabel',sprintfc('%g', [yticks.*y_Scl]))
ylabel(h, 'cd/m^2')% add unit label
title(date); % Show date in image
caxis auto % set axis to auto
datacursormode on % enable datacursor
img = getframe(gcf);
nowstr = datestr(now, 'yyyy-mm-dd_HH_MM_SS');
folder = 'C:\Users\Taiko\Desktop\FalseColor\';
ImageFiles = dir( fullfile(folder, '*.jpg') );
if isempty(ImageFiles)
next_idx = 1;
else
lastfile = ImageFiles(end).name;
[~, basename, ~] = fileparts(lastfile);
file_number_str = regexp('(?<=.*_)\d+$', basename, 'match' );
last_idx = str2double(file_number_str);
next_idx = last_idx + 1;
end
newfilename = fullfile( folder, sprintf('%s_%04d.jpg', nowstr, next_idx) );
imwrite(img.cdata, newfilename);
Problems:
1) You are getting YTick of the figure (gca) but not the color bar. That would give you the "pixel" coordinates of the graph, instead of the actual values. Use yticks = get(h,'YTick');.
2) caxis auto Should come before overwriting YTicks (and after enabling the color bar); otherwise the scale and ticks will mismatch.
3) Do you mean C = 100000?
Result:
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
I am using Octave 3.6.4 to process an image and store it afterwards. The image I read is grayscale, and after calculations the matrix should be of the same type. However, if I open the stored image, there are no gray pixels. There are only black and white ones and the gray ones got lost. They are essentially all white.
Here is the processing code:
function aufgabe13()
[img, map, alpha] = imread("Buche.png");
[imax, jmax] = size(img);
a = 0.7;
M = 255 * ones(imax,jmax + round(imax * a));
for i = 1:imax
begin = round((imax-i)*a);
M(i,begin +1 : begin + jmax) = img(i,:);
end
imwrite(M, 'BucheScherung.png', 'png');
end
So what am I doing wrong?
The reason why is because M is a double matrix so the values are expected to be between [0,1] when representing an image. Because your values in your image are between [0,255] when read in (type uint8), a lot of the values are white because they're beyond the value of 1. What you should do is convert the image so that it is double precision and normalized between [0,1], then proceed as normal. This can be done with the im2double function.
In other words, do this:
function aufgabe13()
[img, map, alpha] = imread("Buche.png");
img = im2double(img); % Edit
[imax, jmax] = size(img);
a = 0.7;
M = ones(imax,jmax + round(imax * a)); % Edit
for i = 1:imax
begin = round((imax-i)*a);
M(i,begin +1 : begin + jmax) = img(i,:);
end
imwrite(M, 'BucheScherung.png', 'png');
end
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'));