From raw bits to jpeg without writing into a file - image

I have a real time application which receives jpg images coded in base64. I do not know how to show the image in matlab without having to save the image in the disk and open it afterwards.
This is the code I have so far, that saves the image in the disk before showing it:
raw = base64decode(imageBase64, '', 'java');
fid = fopen('buffer.jpg', 'wb');
fwrite(fid, raw, 'uint8');
fclose(fid);
I = imread('buffer.jpg');
imshow(I);
Thanks!

You can do it with the help of Java. Example:
% get a stream of bytes representing an endcoded JPEG image
% (in your case you have this by decoding the base64 string)
fid = fopen('test.jpg', 'rb');
b = fread(fid, Inf, '*uint8');
fclose(fid);
% decode image stream using Java
jImg = javax.imageio.ImageIO.read(java.io.ByteArrayInputStream(b));
h = jImg.getHeight;
w = jImg.getWidth;
% convert Java Image to MATLAB image
p = reshape(typecast(jImg.getData.getDataStorage, 'uint8'), [3,w,h]);
img = cat(3, ...
transpose(reshape(p(3,:,:), [w,h])), ...
transpose(reshape(p(2,:,:), [w,h])), ...
transpose(reshape(p(1,:,:), [w,h])));
% check results against directly reading the image using IMREAD
img2 = imread('test.jpg');
assert(isequal(img,img2))
The first part of decoding the JPEG byte stream is based on this answer:
JPEG decoding when data is given in array
The last part converting Java images to MATLAB was based on this solution page:
How can I convert a "Java Image" object into a MATLAB image matrix?
That last part could also be re-written as:
p = typecast(jImg.getData.getDataStorage, 'uint8');
img = permute(reshape(p, [3 w h]), [3 2 1]);
img = img(:,:,[3 2 1]);
imshow(img)

Related

Convert image to array and show again it in image

I'm using the following code to show an image from array which previously converted to array. But the image not show correctly:
I = imread('ut.jpg');
image=mat2gray(I);
imshow(image);
FID = fopen('FileName.txt', 'w');
if FID == -1, error('Cannot create file.'); end
fprintf(FID, '%g %g %g ... %g \n', image);
fclose(FID);
x = 100*rand(512,1500);
fileID = fopen('FileName.txt','w');
fprintf(fileID,'%f',x);
fclose(fileID);
imshow(x);
Bitmaps consist of two things. First: 3 matrices with colour intensities, graduated as uint, numbers from 0 to 255. Second: A header containing information regarding size, colordepth, filelength, etc.
Your program does not create correct images because it misses a header.
Regarding the matlab procedure:
By using imread on a RGB image, you are automatically creating a matrix. If you convert it to grayscale with rgb2gray you will have a single matrix of uint (without any additional layers).
If you want to safe your image after processing it simply use:
I = imread('ut.jpg');
% Convert, do smth e.g. I_new = rgb2gray(I);
filename = 'myNewImage.jpg';
imwrite(I_new,filename);
By using imwrite you automatically create a correct header.

How do I read a RAW RGB image in MATLAB?

I am trying to properly convert a RAW image so that I can view it in MATLAB. Image can be downloaded here. I am using the version of the code provided in How can I read in a RAW image in MATLAB?
However, it is not working properly for me. Here is my slightly modified version below:
clear;
row=966; col=1296;
fin=fopen('C:\Users\user\Desktop\test2.raw','r');
I=fread(fin, col*row*3,'uint8=>uint8'); %// Read in as a single byte stream
I = reshape(I, [col row 3]); %// Reshape so that it's a 3D matrix - Note that this is column major
Ifinal = flipdim(imrotate(I, -90),2); % // The clever transpose
imshow(Ifinal);
fclose(fin); %// Close the file
What I get:
What I should get:
I'm not sure why it's not working for me but if I use an imaging program (ImageJ) I can correctly convert the RAW file if I select Image type as '24-bit BGR'. The pixel format of the image is 8 Bit BAYRG.
There you go:
function q43127920
row=966; col=1296;
fin=fopen('test.raw','r');
I = fread(fin, col*row*3,'ubit24=>uint32');
I = reshape(I, col, row, []);
B = uint8(bitand(bitshift(I,-00),uint32(255)));
G = uint8(bitand(bitshift(I,-08),uint32(255)));
R = uint8(bitand(bitshift(I,-16),uint32(255)));
I = cat(3,R,G,B);
Ifinal = flip(imrotate(I, -90),2);
imagesc(Ifinal);
fclose(fin);
Result:

Reading & Writing Grayscale TIF files in Matlab

I'm trying to extract a (very) large number of subimages from a large grayscale TIF file and save each image as a GIF, PNG, or even another TIF using MATLAB. I'm able to display the individual images using imshow(sub(:,:,1),cmap) but when I try to write the data to an image file, the generated files are just white squares 101x101 px. Using the cmap argument in imwrite produces the same result, as does changing the image format (I've tried with PNG, TIF, GIF, and JPG with no luck). The file a.tif is 16 bit according to the property menu in Windows Explorer. Any help is appreciated. I'm really at wit's end with this.
% Import coordinates array and correct for multiplication by 10
datafile = 'data.xlsx';
coords = xlsread(datafile,1,'G2:H13057');
x = coords(:,1) ./ 10;
y = coords(:,2) ./ 10;
r = 50;
[img, cmap] = imread('a.tif'); % import the image
s = 2*r+1; % scalar of size of each submatrix in the array (sise of image)
sub = zeros(s,s,num); % create 3D matrix/array of matrices. Each submatrix corresponds to 50 px box around each point
i = 1:4;
subrgb = zeros(s,s,num);
for i=1:4
sub(:,:,i) = img((y(i)-r):(y(i)+r),(x(i)-r):(x(i)+r));
filename = 'dot_%d.png';
filename = sprintf(filename,i);
imwrite(sub(:,:,i),filename,'png');
end
Try changing the line:
sub = zeros(s,s,num);
to:
sub = zeros(s,s,num,class(img));
I assume that the problem is that sub is of type double.
Good luck

MATLAB: How to change pixel values after using VideoReader

I'm trying to read a video file using VideoReader and change some pixel values and save it back to the video file. I can easily change the matrix values but how do I save it back into the video file?
obj = VideoReader('DemoClip.asf');
imageData = read(obj);
imageData(17,32,:) = 65;
Here is a way to do it using videoWriter. The code is commented; if something is unclear please ask. I used the demo xylophone.mp4 file from Mathworks.
clear
clc
close all
xyloObj = VideoReader('xylophone.mp4');
imageData = read(xyloObj);
%// Open writer object
writerObj = VideoWriter('NewVideo.avi');
open(writerObj);
%// Show 1st frame
hIm = imshow(imageData(:,:,:,1));
for k = 1:size(imageData,4)
%// Change pixel values
imageData(1:200,1:200,:,k) = uint8(0);
%// Refresh cdata property. Faster than calling repetitevely imshow
set(hIm,'CData',imageData(:,:,:,k));
drawnow
frame = getframe;
%// Write to video file
writeVideo(writerObj,frame);
end
close(writerObj);
Sample frame of the resulting video:

Change Range Of Displayed Pixel Values from Command Line?

I'm working with some MRI data in Matlab 2014b, but the data is formed of intensity values not RGB. To get around this I use the code below to form a movie out of the MRI frames (I'm working on dynamic data here)
My problem is that the images need to have altered display values for the pixels, as the default only displays between -Inf and Inf, and I need between 0 and 0.25 to get a sensible image out of my data.
Are there any ways to pass that change from the script in to the movie, and then to write to file? I can only seem to do this per image in implay, and I'd like an automated way to edit each image and then store as a frame for a movie..?
%Code for producing movie.
graymap = gray(256);
for i = 1:32
a(:,:,i) = cmunique(Reformed_Data_Colourmap(:,:,i));
end
for i = 1:32
b = im2frame(a(:,:,i),graymap);
a(:,:,1) = ((b.cdata));
image(a(:,:,1))
colormap 'gray'
%The change needs to be here, to display pixel values from 0 to 0.25, to allow for a sensible image from the MR data.
frames(1,i) = getframe;
end
movie(frames)
The solution is provided:
for i = 1:32
b = im2frame(a(:,:,i),graymap);
a(:,:,1) = ((b.cdata));
clims = [0 250];
%image(a(:,:,1),clims)
colormap 'gray'
imagesc(a(:,:,1),clims);
%set('window', [0 400])
frames(1,i) = getframe;
end
clims solves the issue.

Resources