Save a double matrix as an image file in MATLAB - image

I have a matrix sig_matrix of data type double, the values are like:
3,0450 3,0450 3,0450
2,6200 2,6050 2,5900
2,5250 2,5200 2,5150
2,3800 2,3800 2,3650
2,6050 2,6650 2,7350
I need to save as an image file, but the problem is: image types like jpg, png only accepts integer data (uint8, uint16), but I really need to save the data as double.
I tried to save as a TIF file using the code below:
t = Tiff('test.tif', 'w8');
setTag(t,'Photometric',Tiff.Photometric.RGB);
setTag(t,'ImageLength',length(sig_matrix));
setTag(t,'ImageWidth',length(sig_matrix));
setTag(t,'BitsPerSample',64);
setTag(t,'SamplesPerPixel',3);
setTag(t,'SampleFormat', 3);
setTag(t,'PlanarConfiguration',Tiff.PlanarConfiguration.Chunky);
setTag(t,'Compression',Tiff.Compression.None);
write(t,repmat(sig_matrix, [1 1 3]));
close(t);
It worked, but then I tried to convert this file to yuv (using ffmpeg for example) but I got an error (Invalid TIFF header to be more specific).
So, I need to save a double matrix as a image file and then convert to yuv.
Anyone could help me please?
Obs.: I can't use mat2gray or something like that because I need that specific double data to convert to yuv

Related

Build Image from pixel array - Flutter

Tensorflow-Lite's Pix2Pix implementation outputs a Uint8List:
Uint8List input;
var output = await Tflite.runPix2PixOnBinary(binary: input, asynch: true);
The result now has be converted to an Image object in order to display it.
This is the problem.
It seems like pictures have some kind of header or signature, which is essential for the decodeImage() function of the
Image package or similar decode functions (MemoryImage, Image.memory, decodeImageFromList).
This answer offers a solution, unfortunately it is only for 256 different colors (one channel?). TfLite outputs x channels tho...
I am looking for something like the Python Pillow Package and its function
new_image = Image.fromarray(array)
or some other approach to display the Pix2Pix output.
Thanks!

Cutting data appended to a .jpg file and save as mpg file

The background of my problem is that I want to extract the video data of Motion Photos (taken by my Samsung S7). Manually it is easy but time consuming. Just open the .jpg file in a HexEditor and extract all data after the line "MotionPhoto_Data". The first part is the image and the second part is the video.
My current code is
im = 'test.jpg'
with open(im, 'rb') as fin:
data = fin.read()
data_latin = data.decode('latin1')
fin.close()
position = data_latin.find('MotionPhoto_Data')
data_pic = data[:position]
data_mpg = data[position:]
My problem now is that I can´t figure out how to save these strings in a way that data_pic is saved as a working jpg and data_mpg as a working video.
I tried
with open('test_pic.jpg', 'a') as fin:
fin.write(str(data_pic))
fin.close()
But this didn´t worked. I think there is a basic issue on how I try to handle/save my data but I can´t figure out how to fix this.
I assume you use python 3 as it is tagged that way.
You should not decode with 'data.decode('latin1'). It is binary data.
data = fin.read()
Then later write it also as binary data:
with open('test_pic.jpg', 'ab') as fout:
fout.write(data_pic)
fout.close()

Image Copy Issue with Ruby File method each_byte

This problem has bugged me for a while.
I have a jpeg file that is 34.6 kilobytes. Let's call it Image A. Using Ruby, when I copy each line of Image A to a newly created file, called Image B, it is copied exactly. It is exactly the same size as Image A and is accessible.
Here is the code I used:
image_a = File.open('image_a.jpg', 'r')
image_b = File.open('image_b.jpg', 'w+')
image_a.each_line do |l|
image_b.write(l)
end
image_a.close
image_b.close
This code generates a perfect copy of image_a into image_b.
When I try to copy Image A into Image B, byte by byte, it copies successfully but the file size is 88.9 kilobytes rather than the 34.6 kilobytes. I can't access Image B. My mac system alerted me it may be damaged or is using a file format that isn't recognized.
The related code:
//same as before
image_a.each_byte do |b|
image_b.write(b)
end
//same as before
Why is Image B, when copied into byte by byte, larger than Image A? Why is it also damaged in some way, shape, or form? Why is Image A the same size as B, when copied line by line, and accessible?
My guess is the problem is an encoding issue. If so, Why does encoding format matter when copying byte by byte if they translate into the correct code points? Are code points jumbled up into each other so the parser is unable to differentiate between them?
Do \s and \n matter? It seems like it. I did some more research and I found that Image A had 128 lines of code whereas Image B had only one line.
Thanks for reading!
IO#each_byte iterates over bytes (aka Integers). IO#write, however, takes a string as an argument. So it converts the integer to a string via to_s.
Given the first byte in your image is 2551, you'd write the string "255" into image_b. This is why your image_b gets larger. You write number-strings into it.
Try the following when writing back bytes:
image_a.each_byte do |l|
image_b.write l.chr
end
1 As #stefan pointed out jpeg images start with FF D8. So the first byte is 255.

Opencv cvSaveImage

I am trying to save an image using opencv cvSaveImage function. The problem is that I am performing a DCT on the image and then changing the coefficients that are obtained after performing the DCT, after that I am performing an inverse DCT to get back the pixel values. But this time I get the pixel values in Decimals(e.g. 254.34576). So when I save this using cvSaveImage function it discards all the values after decimals(e.g. saving 254.34576 as 254) and saves the image. Due to this my result gets affected. Please Help
"The function cvSaveImage saves the image to the specified file. The image format is chosen depending on the filename extension, see cvLoadImage. Only 8-bit single-channel or 3-channel (with 'BGR' channel order) images can be saved using this function. If the format, depth or channel order is different, use cvCvtScale and cvCvtColor to convert it before saving, or use universal cvSave to save the image to XML or YAML format."
I'd suggest investigating the cvSave function.
HOWEVER, a much easier way is to just write your own save/load functions, this would be very easy:
f = fopen("image.dat","wb");
fprintf(f,"%d%d",width,height);
for (y=0 to height)
for (x=0 to width)
fprintf(f,"%f",pixelAt(x,y));
And a corresponding mirror function for reading.
P.S. Early morning and I can't remember for the life of me if fprintf works with binary files. But you get the idea. You could use fwrite() instead.

MATLAB - image huffman encoding

I have a homework in which i have to convert some images to grayscale and compress them using huffman encoding. I converted them to grayscale and then i tried to compress them but i get an error. I used the code i found here.
Here is the code i'm using:
A=imread('Gray\36.png');
[symbols,p]=hist(A,unique(A))
p=p/sum(p)
[dict,avglen]=huffmandict(symbols,p)
comp=huffmanenco(A,dict)
This is the error i get. It occurs at the second line.
Error using eps
Class must be 'single' or 'double'.
Error in hist (line 90)
bins = xx + eps(xx);
What am i doing wrong?
Thanks.
P.S. how can i find the compression ratio for each image?
The problem is that when you specify the bin locations (the second input argument of 'hist'), they need to be single or double. The vector A itself does not, though. That's nice because sometimes you don't want to convert your whole dataset from an integer type to floating precision. This will fix your code:
[symbols,p]=hist(A,double(unique(A)))
Click here to see this issue is discussed more in detail.
first, try :
whos A
Seems like its type must be single or double. If not, just do A = double(A) after the imread line. Should work that way, however I'm surprised hist is not doing the conversion...
[EDIT] I have just tested it, and I am right, hist won't work in uint8, but it's okay as soon as I convert my image to double.

Resources