How to Split frame into two images (even field and odd field) from Interlaced (NV12 format )raw data - interlacing

I have raw NV12 YUV progressive Data and required to split each frame into images with even and odd fields (interlaced data).

If you want to do all the jobs manally:
Extract each frame from .yuv file
Depending on the format and resolution of your stream, caculate the size of one frame. Then, you can do the extration.
Split .yuv frame into .yuv field
Caculate the size of each line, and split the frame by odd/even line. Please take care of the uv line if the format is yuv420.
Covert .yuv field to .bmp image
If the format is not yuv444, then convert it to yuv444 first. Then, do the yuv to rgb convertion, and store the image into .bmp format.
With the help of ffmpeg and ImageMagick, it can also be done (more easier) by two steps (supposing that the resolution of frame is 1920x1080 and field is 1920x540) :
Convert YUV to Images
ffmpeg -s 1920x1080 -i input.yuv frame_%3d.bmp
-pix_fmt can be used to specify the format(pixel layout) of .yuv file.
Split Images to Odd/Even
convert frame_000.bmp -define sample:offset=25 -sample 100%x50% frame_000_top.bmp
convert frame_000.bmp -define sample:offset=75 -sample 100%x50% frame_000_bot.bmp
These two commands can be found in the last part of de-interlace a video frame.

Related

Lossless compression of a sequence of similar grayscale images

I would like to have the best compression ratio of a sequence of similar grayscale images. I note that I need an absolute lossless solution (meaning I should be able to check it with an hash algorithm).
What I tried
I had the idea to convert my images into a video because there is a chronology between images. The encoding algorithm would compress using the fact that not all the scene change between 2 pictures. So I tried using ffmpeg but I had several problems due to sRGB -> YUV colorspace compression. I didn't understand all the thing but it's seems like a nightmare.
Example of code used :
ffmpeg -i %04d.png -c:v libx265 -crf 0 video.mp4 #To convert into video
ffmpeg -i video.mp4 %04d.png #To recover images
My second idea was to do it by hand with imagemagik. So I took the first image as reference and create a new image that is the difference between image1 and image2. Then I tried to add the difference image with the image 1 (trying to recover image 2) but it didn't work. Noticing the size of the recreated picture, it's clear that the image is not the same. I think there was an unwanted compression during the process.
Example of code used :
composite -compose difference 0001.png 0002.png diff.png #To create the diff image
composite -compose difference 0001.png diff.png recover.png #To recover image 2
Do you have any idea about my problem ?
And why I don't manage to do the perfect recover with iamgemagik ?
Thanks ;)
Here are 20 samples images : https://cloud.damien.gdn/d/f1a7954a557441989432/
I tried a few ideas with your dataset and summarise what I found below. My calculations and percentages assume that 578kB is a representative image size.
Method 1 - crush - 69%
I just ran pngcrush on one of your images like this:
pngcrush -bruteforce input.png crushed.png
The output size was 400kB, so your image is now only taking 69% of the original space on disk.
Method 2 - rotate and crush - 34%
I rotated your images through 90 degrees and crushed the result:
magick input.png -rotate 90 result.png
pngcrush -bruteforce result.png crushed.png
The rotated crushed image takes 34% of the original space on disk.
Method 3 - rotate and difference - 24%
I rotated your images with ImageMagick, then differenced two adjacent images in the series and saved the result. I then "pngcrushed" that which resulted in 142kB, or 24% of the original space.
Method 4 - combined to RGB - 28%
I combined three of your single channel images into a 3-channel RGB image and pngcrushed the result:
magick 000[123].png -combine result.png
pngcrush -bruteforce result.png crushed.png
That resulted in a 490kB file containing 3 images, i.e. 163kB per image or 28% of the original size.
I suspect video with "motion" estimation/detection would yield the best results if you are able to do it losslessly.
You might get some gain out of MNG, which is intended for lossless animation compression. You can use libmng to try it out.

With ffmpeg's example extract_mvs.c, I am getting black and white images from color rtsp camera

I am using the extract_mvs.c from ffmpeg:
https://ffmpeg.org/doxygen/2.5/extract__mvs_8c_source.html
I added opencv to imwrite the image.
cv::Mat img(frame->height,frame->width,CV_8UC1,frame->data[0]);
imwrite( "pic.jpg", img );
That works because the image in the frame is in grayscale. The camera is a color camera however, and I dont know why I am getting grayscale. If I cange the above to CV_8UC3, I get segmentation fault.
I tried to save the image with ppm_save function and I still get a black and white frame when there should be a color frame. Any ideas?
Thanks,
Chris
Just read about graphics file formats and such. JPG requires BGR24 format. The raw frame buffer format YUV420P needs to be converted to BGR24 using swscale. Then the output frames height and width needs to be manually set before calling :
cv::Mat img(out_frame->height,out_frame->width,CV_8UC3,out_frame->data[0]);
imwrite( "pic.jpg", img );
Likewise,PPM file format requires RGB24 and the raw format needs to be converted to this before saving the ppm file.
Thanks,
Chris

Image compression using Lossy Compression technique

I need to convert PNG to JPEG,JPEG 2000 using ImageMagick and Matlab. I want to compress all data with ratio ( e.g. 10) and then specify some file size? Any idea or solution to achieve the specific file size? How can I do it? Thanks
Imagemagick can create a JPG of your desired file size. See http://www.imagemagick.org/Usage/formats/#jpg
-define jpeg:extent={size}
As of IM v6.5.8-2 you can specify a maximum output filesize for the JPEG image. The size is specified with a suffix. For example "400kb".

Resize image preserving exif data: focal length etc

What converter(like imagemagick) can be used to convert images with exif data preserving it?
What if I downscale images 4 times? Should I also change the focal length?
Data I have extracted from my JPG photo with exiftool
Focal Length : 50.0 mm (35 mm equivalent: 50.0 mm)
EDIT:
Seems imagemagick preserve exif data:
mogrify -resize 25% -path output_foler/ *.JPG
I believe newer versions of Imagemagick should preserve the metadata. A fall back would be to use Exiftool to copy the data with a command like exiftool -tagsfromfile OldFile -all:all NewFile.
Both of those are platform independent. To be more precise with other programs, you will need specify your OS. For example, with Windows, you can use Irfanview to convert images and it will retain most metadata as long as you enable those options.

Matlab: how to save TIFF with transparency or PNG with no compression?

I have to process a lot of images and save results to image files with transparency in Matlab. But PNG compression takes too much time for me. How can I save PNG with no compression or TIFF with transparency? Are there other ways to save an image without compression and with transparency?
It's my first question here, sorry for my bad English and wrong question style if there are any mistakes in question.
Using the TIFF class in Matlab you can write TIFFs with transparancy:
%# create a synthetic RGBA image
ch = checkerboard(100);
rgba = repmat(ch,[1,1,4]);
rgba(:,:,4) = rgba(:,:,4)==0;
rgba = uint8(round(rgba*255));
%# create a tiff object
tob = Tiff('test.tif','w');
%# you need to set Photometric before Compression
tob.setTag('Photometric',Tiff.Photometric.RGB)
tob.setTag('Compression',Tiff.Compression.None)
%# tell the program that channel 4 is alpha
tob.setTag('ExtraSamples',Tiff.ExtraSamples.AssociatedAlpha)
%# set additional tags (you may want to use the structure
%# version of this for convenience)
tob.setTag('ImageLength',size(ch,1));
tob.setTag('ImageWidth',size(ch,2));
tob.setTag('BitsPerSample',8);
tob.setTag('RowsPerStrip',16);
tob.setTag('PlanarConfiguration',Tiff.PlanarConfiguration.Chunky);
tob.setTag('Software','MATLAB')
tob.setTag('SamplesPerPixel',4);
%# write and close the file
tob.write(rgba)
tob.close
%# open in Photoshop - see transparency!
Matlab's imwrite does not have parameter for the PNG compression level. If it did, you could set it to zero for no compression. While for TIFF it does have a none option for Compression, there is no alpha channel. You can write to the old Sun Raster (RAS) format with an alpha channel and no compression. Though nothing would likely be able to read it.
"There is no uncompressed variant of PNG. It is possible to store uncompressed data by using only uncompressed deflate block"
The uncompressed deflate block uses a header of 5 bytes + up to 65535 bytes of uncompressed data per block.
http://www.w3.org/TR/PNG-Rationale.html