Image Color is not proper when converted to PIL - python-imaging-library

I am converting tensor to pil image, but color is distorted. I have tried converting it to BGR but result is still same.
trsn = transforms.ToPILImage()
temp = (target + torch.mean(target)) *torch.std(target)
res = trsn(temp.to('cpu').detach().squeeze())
np_img=np.array(res)
bgr = cv2.cvtColor(np_img,cv2.COLOR_RGB2BGR)
pil_im = Image.fromarray(bgr)
print(res)
# plt.imshow(res)
plt.imshow(res,label="Epoch "+str(i))
plt.show()
# im=Image.fromarray(np.uint8(target.to('cpu').detach().numpy()*255))
pil_im.save('f.jpeg')
I have a function that converts tensor to numpy and can show image on matplotlib.
Here is the function
def imcnvt(image):
x = image.to("cpu").clone().detach().numpy().squeeze()
x = x.transpose(1,2,0)
x = x*np.array((0.5,0.5,0.5)) + np.array((0.5,0.5,0.5))
return torch.Tensor(x)
Here is the pic I get
and here is the pic I want with PIL

Related

Not enough input arguments error in the imread statement

function img3bitcolor = img2coe3(image_in,file_coe)
%SUMPROD Creat file .coe from image PNG or JPEG
% image file is 3 bit RGB => 8 colors
% Creat file coe
img = imread(image_in);%Read image
height = size(img,1);%Take height image
width = size(img,2);%Take width image
s = fopen(file_coe,'wb');%Open file coe with mode write
fprintf(s,'%s\n','; VGA Memory Map ');
fprintf(s,'%s\n','; .COE file with bit coefficients ');
fprintf(s,';Height : %d, Width : %d\n\n',height,width);
fprintf(s,'%s\n','; Data image is bit => coefficients is 2');
fprintf(s,'%s\n','memory_initialization_radix=2;');
fprintf(s,'%s\n','memory_initialization_vector=');
img3bitcolor = img;
end
After running the program:
Not enough input arguments.
Error in img2coe3 (line 6)
img = imread(image_in);%Read image

Unable to save iverseftt image and image K-Space in matlab

I have a brain MRi image in .png format. I read the image and extract the K-Space and set some of the K-Space as 0
img_fft = fftshift(fft2(img));
sizes = size(img_fft);
row_half = sizes(1)/2;
flag = true;
for r = row_half:sizes(1)
for c = 1:sizes(2)
img_fft(r,c) = 0+1i*0;
end
end
After this I change the image back to image space using
img_back = ifft2(ifftshift(img_fft));
and after this I cast the image to uint8 as that was the original image format.
When I try to plot my image using imshow() I get a different output compared to when I write the image using imwrite. Also if I use abs(img_back) in imwrite I get an error.
Error using abs: Complex integers are not supported.
My plotting code is below:
img_back = ifft2(ifftshift(img_fft));
img_back = cast(img_back,'uint8');
subplot(1,3,1), imshow(img)
subplot(1,3,2), imshow(img_back)
subplot(1,3,3), imshow(abs(img_fft),[])
imwrite(abs(img_back),'back_img.png','png')
Can someone tell me what I am doing wrong here?
Take absolute value after inverse Fourier transform and then cast the result to uint8 type:
img_back = abs(ifft2(ifftshift(img_fft)));
img_back = cast(img_back,'uint8');

How to convert Matlab's Tiff function in Octave?

I'm trying to convert a function I use in MATLAB to merge an RGB image with an IR image (both in JPG formats) to create a Tiff image with 4 bands (R, G, B, IR). However, I have some problem implementing the Tiff function, as it looks like that Tiff is not implemented in Octave.
Someone know how can I convert the Tiff part of following function to Octave?
for fidx = 1:numel(filelist1)
rgb = imread(fullfile(folder1, filelist1{fidx}));
numrows = size(rgb,1);
numcols = size(rgb,2);
ir = imread(fullfile(folder2, filelist2{fidx}));
data = cat(3,rgb,ir);
t = Tiff(fullfile(folderout, sprintf(outfilepattern, fidx))','w');
setTag(t,'Photometric',Tiff.Photometric.RGB);
setTag(t,'Compression',Tiff.Compression.None);
setTag(t,'BitsPerSample',8);
setTag(t,'SamplesPerPixel',4);
setTag(t,'SampleFormat',Tiff.SampleFormat.UInt);
setTag(t,'ExtraSamples',Tiff.ExtraSamples.Unspecified);
setTag(t,'ImageLength',numrows);
setTag(t,'ImageWidth',numcols);
setTag(t,'TileLength',32);
setTag(t,'TileWidth',32);
setTag(t,'PlanarConfiguration',Tiff.PlanarConfiguration.Chunky);
write(t,data);
close(t);

How to convert rgb to gray but keep one colour unchanged

I have an image in which I want to only keep the green part and convert the others to gray scale.
It seems from the colors in your image, that the greens are actually so close to grayscale that you'll be unable to see anything. Either way this is how you do it:
im = imread('houses.jpg');
s= (im(:,:,2)>im(:,:,1))&(im(:,:,2)>im(:,:,3));
dim = double(im);
r = abs(dim(:,:,2)-((dim(:,:,1))+dim(:,:,2)+dim(:,:,3))/3) < 3;
q = s|r;
imgs = rgb2gray(im);
imgs3(:,:,1) = imgs;
imgs3(:,:,2) = imgs;
imgs3(:,:,3) = imgs;
imout = zeros(size(im));
for i=1:size(im,1),
for j=1:size(im,2),
if q(i,j) == 0,
imout(i,j,:) = imgs3(i,j,:);
else,
imout(i,j,:) = im(i,j,:);
end
end
end
imshow(uint8(imout))
imwrite(uint8(imout),'output.jpg');
if you want to see something useful you would probably want to do the following
im = imread('houses.jpg');
s= (im(:,:,2)>im(:,:,1))&(im(:,:,2)>im(:,:,3));
dim = double(im);
r = abs(dim(:,:,2)-((dim(:,:,1))+dim(:,:,2)+dim(:,:,3))/3) < 3;
q = s|r;
imgs = rgb2gray(im);
imgs3(:,:,1) = imgs;
imgs3(:,:,2) = imgs;
imgs3(:,:,3) = imgs;
imout = zeros(size(im));
for i=1:size(im,1),
for j=1:size(im,2),
if q(i,j) == 0,
imout(i,j,:) = imgs3(i,j,:);
else,
imout(i,j,1) = im(i,j,1);
imout(i,j,2) = 255;
imout(i,j,3) = im(i,j,3);
end
end
end
imshow(uint8(imout))
imwrite(uint8(imout),'output.jpg');
which gives this as result:
It should be something like this:
gray_img = rgb2gray(img);
green_mask = img(:,:,2) > img(:,:,1) & img(:,:,2) > img(:,:,3);
gray_img3 = cat(3, gray_img, gray_img, gray_img);
green_mask3 = cat(3, green_mask, green_mask, green_mask);
output_img = gray_img3;
output_img(green_mask3) = img(green_mask3);
I didn't check it, but I'm quite sure it should do the work.
The only thing you might want to modify is the computation of the mask, currently it will include all pixels that are more green than red or blue, but you may want to be more (or less) specific in choosing which pixels to leave unchanged.
I would suggest to use a purely hue=based approach, as you are interested in a specific color.
My approach would be to convert your images to the HSV colorspace and check the Hue channel.
img=imread('houses.jpg');
hsv=rgb2hsv(img);
% find the white areas of the image
gray_part=hsv(:,:,3)>0.7;
% find the green areas of the image that are not white
green_part=hsv(:,:,1)>(30/360) & hsv(:,:,1)<(210/360) & ~gray_part;
% create the output image
outimg=(uint8(double(img).*repmat(green_part,[1 1 3])));
figure;
subplot(121); imshow(img);
subplot(122); imshow(outimg);
This will give you the following image (left: original, right: resulting masked image):
Of course, if you need to get the rest of the image in grayscale you may use the previous results as follows:
pixel(1,1,1)=0;pixel(1,1,2)=255;pixel(1,1,3)=0;
green_img=repmat(pixel,[size(img,1) size(img,2), 1]);
green_part=repmat(green_part,[1 1 3]);
gray_img=rgb2gray(uint8(double(img).*~green_part));
gray_img=double(repmat(gray_img,[1 1 3]));
outimg=uint8(green_part.*green_img + gray_img);
figure; imshow(outimg);
This will display the image shown below:

Matlab: Check all images in a directory for grayscale?

I want to check all jpg-images in the current directory if they are grayscale or contain coloured pixels... I tried:
figdirectory = pwd;
fullpath = sprintf('%s/*.jpg', figdirectory);
d = dir(fullpath);
% Loop
pages = [];
for i = 1:length(d)
f = d(i).name;
fname_input = sprintf('%s/%s', figdirectory, f);
A = imread(fname_input);
B = rgb2gray(A);
if(A-B == 0)
hascolor = 0;
else
hascolor = 1;
end
pages = [pages; hascolor];
end
but this gives me an error about the matrix dimensions of A and B. Why has A a third dimension?
Thanks!
To do that:
0) Assuming your input is purely an 'image' and not a 'volume'.
1) [r c d] = size(im);
2) if d is larger than 1, then it is a colored image
3) other wise, it has to be a gray-scale image.
EDITS:
You can add one more condition to solidly distinguish grey scale img from color ones. Assuming ur color imgs are of 3 channels,
if d is equal to 3 then check if all 3 channels are equal
im(:,:,1)==im(:,:,2) && im(:,:,1)==im(:,:,3)
Then you have an grayscale image otherwise color img
Here is one simple solution based on IMFINFO:
%# some test images shipped with the Image Processing Toolbox
fNames = {
'circles.png' %# binary
'shadow.tif' %# indexed color
'coins.png' %# gray
'peppers.png' %# RGB
};
isGrayscale = false(size(fNames));
for i=1:numel(fNames)
imgInfo = imfinfo(fNames{i});
if strcmp(imgInfo.ColorType,'truecolor')
isGrayscale(i) = false;
elseif strcmp(imgInfo.ColorType,'grayscale')
isGrayscale(i) = true;
elseif strcmp(imgInfo.ColorType,'indexed')
%# indexed images colormap (the three channels should be all same)
isGrayscale(i) = all(all( diff(imgInfo.Colormap,[],2)==0 ,2),1);
end
end
The first part in your case can be:
dirName = 'C:\path\to\myimages';
files = dir( fullfile(dirName,'*.jpg') );
fNames = {files.name}';
EDIT:
#Adrian: With regards to the image you posed, as far as the image format saved, it IS a color image. Now the fact that all R/G/B channels are all the same is simply a special case...
Anyway if you want to be able to detect such cases, change the 'truecolor' part of the above code to:
#% ...
if strcmp(imgInfo.ColorType,'truecolor')
img = imread(fNames{i});
isGrayscale(i) = isequal(img(:,:,1),img(:,:,2),img(:,:,3));
elseif strcmp(imgInfo.ColorType,'grayscale')
#% ...
You can use IMFINFO for this task, so that you won't have to load the image into memory.
figdirectory = pwd;
fullpath = sprintf('%s/*.jpg', figdirectory);
d = dir(fullpath);
nImages = length(d);
%# imageType is a cell array with either 'grayscale', 'truecolor', or 'indexed',
%# depending on the kind of image you have.
imageType = cell(nImages,1);
for iImg = 1:nImages
info = imfinfo(d(iImg).name);
imageType{iImg} = info.ColorType;
end
%# isGrayscale is true for grayscale images, false otherwise
%# (though note that there might be mapped images that map to a grayscale colormap).
isGrayscale = cellfun(#(x)strcmp(x,'grayscale'),imageType);
EDIT
%# the indexed images have to be loaded in order for you to check
%# for grayscale maps
indexedIdx = find(cellfun(#(x)strcmp(x,'indexed'),imageType));
for iImg = indexedIdx(:)'
[~,map] = imread(fullfile(figDirectory,d(iImg).name));
%# It's a grayscale image if rgb map values are all equal
isGrayscale(iImg) = all(all(bsxfun(#eq,map,map(:,1)),2),1);
end
%# finally, it is possible that the images are *stored* as truecolor
%# but containing, in fact, a grayscale image
truecolorIdx = find(cellfun(#(x)strcmp(x,'truecolor'),imageType));
for iImg = truecolorIdx(:)'
img = imread(fullfile(figDirectory,d(iImg).name));
%# It's a grayscale image if rgb map values are all equal
isGrayscale(iImg) = all(all(all(bsxfun(#eq,img(:,:,1),img),1),2),3);
end
From the manual for imread http://www.mathworks.co.uk/help/techdoc/ref/imread.html
If the file contains a grayscale image, A is an M-by-N array. If the
file contains a truecolor image, A is an M-by-N-by-3 array.
So A will have a third dimension for the coloured images.
If you want to test for greyscale then you could convert the image to hsv.
B = rgb2hsv(A)
from the manual, http://www.mathworks.co.uk/help/techdoc/ref/hsv2rgb.html
When B(:,2) is 0, the colors are unsaturated (i.e., shades of gray).
In the case of a true colour image like the one posted it will be if unique(B(:,:,2)) is zero, hence
A = imread(fname_input);
B = rgb2hsv(A);
%# if saturation levels are zero then it's a greyscale image
if(unique(B(:,:,2)) == 0)
hascolor = 0;
else
hascolor = 1;
end