View Feed
group-icon
Coffee Room
Discuss anything here - everything that you wish to discuss with fellow engineers.
12833 Members
Join this group to post and comment.
prestonee
prestonee • Aug 1, 2008

Matlab AVI help

Hi I have been given an issue outside of my expertise to help the testing group with a imaging scene based nuc model in matlab. I have the thing working ( even Im suprised) but my issue is exporting the results.

What i have is a grayscale video coming in, a windowed part getting manipulated, drawing a box on the 'figure' outlining the windowed area, then saving it to an avi.

Its the last part thats killing me, I'm not able to export directly to avi etc due to lack of memory remaining from the initial video matrix. So what I am doing so far is outputting a 16bit grayscale image of each frame, then at the end reading this back in using matlabs built in's : imread ( which is perserving the 16bit) and getframe( which is downconverting to 8 bit) and addframe.

2 issues

1: since im superimposing the square on the picture in the figure, i lose the square in the video, not a hug deal since im guessing i just need to go in to those pixels and manually change them to black, but im pointing this out incase theirs an easier way of doing this. i know in simulink this would be a single box but am trying to stay away from that.

2: i need to keep this image 16 bit, since the focus is on image noise, i cant lose 8 bits of lsb's and get blurring before the video starts.

This doesn't have to stay in avi format, but from what I've read avi does support 16 bit, i just need to find another way placing the image into the frame instead of the getframe command.

Any help or direction would be good.

EDIT: I went ahead with some for loops to draw the rectangle inside the image, still cant find a way to preserve the 16 bit .png grayscale image when converting to avi. Help please

, PrestonEE
why u aint using simulink???....i will suggest you to use some other format of pic
prestonee
prestonee • Aug 4, 2008
Well Im not using simulink because im not aware of how exactly to do individual pixel processing.

That and once we get the matlab code finalized I will be implementing it into hardware.

I think my limiter atm is the getframe() function, it only supports 8 bit, do you know of any equivalents that support 16 bit? I realize that for human eye its very difficult to tell but it would be good to at least get 10bit on screen.
xheavenlyx
xheavenlyx • Aug 6, 2008
Some points are in order:

1. Try this: MATLAB(help): "movie"

use "movie" to create a movie based on frames, keep adding each frame to the "movie" object. and then use "movie2avi". I have never tried this but just in case it works.Plus try deleting useless or redundant frames OR actually reducing the framerate.

2. I cant understand the 16bit/8bit deal. I think (from my experiences) that those numbers refer to the "color: bit depth" otherwise, video quality depends on the resolution rite? As the pixel values contain only the color information.

3. Can you share the code? I will run it and try to figure it out.

I just wanna thank you for writing a wonderful post. Usually we get Questions without even explaining what the program does.
prestonee
prestonee • Aug 7, 2008
Thank you for the reply =)

The bit thing:

This is not a color image but grayscale so the array is only a 3 dim array of row,col,frame
the value contained in the array represents intensity and is 16 bit
The reason we are using 16 bit is because our images have a signal range as far as intensity from val = 0 to val ~= 35000
The high end changes depending on the scene being captured but doesnt go beyond 16bits.

The issue:

The avi file that im currently generating is 8bit so the range is cut in half providing less shades between black and white. The pixel resolution doesnt change but the 'resolution of the intensity is decreased making pixels that were once slightly different in the image now look identical.

Code:

Here is the code that im using to do this part of the program: notice im only doing an avi of a partial of the original image. Also I am storing the images as .png to preserve the 16 bit values. I did an aviread() to verify that the avi file is 8bit, while a imread() of the stored image shows 16 bit.

imwrite(temp(1:400,300:656,i),strcat('D:\Bar\300\matlab\images_temp\temp',num2str(i),'.png'),'png');
mov = avifile('MOVIE.avi');
count=0;
for i=1:number_of_frames
name1=strcat(name,num2str(i),filetype);
a=imread(strcat(
'D:\BAR\300\matlab\images_temp\',name1));
while count<2
count=count+1;
imshow(a);
F=getframe(gca);
mov=addframe(mov,F);
end
count=0;
end
close all
mov=close(mov);

I will be pursuing what you mentioned while you look into the code, again thank you
xheavenlyx
xheavenlyx • Aug 10, 2008
I will get back to you soon. Its 2 Am here 😀 trying the code was fun but tiering! Sorry for later reply.
xheavenlyx
xheavenlyx • Aug 12, 2008
Here is what I have discovered:

Problem:

The avi file that im currently generating is 8bit so the range is cut in half providing less shades between black and white. The pixel resolution doesnt change but the 'resolution of the intensity is decreased making pixels that were once slightly different in the image now look identical.


Analysis:


You are using two main functions in your program:

"getframe()" and "addframe()", the later one is used to add a frame to your open AVI file.

However, the "addframe()" function adds frame to your AVI file with 8-bit precision, even if you open a .png file of 16-bit precision.

Here is an extract from "addframe()" help [[LINK]]:

aviobj = addframe(aviobj, frame)...frame can be either an indexed image (m-by-n) or a truecolor image (m-by-n-by-3) of double or uint8 precision.
Now, initially I too was confused with uint8/uint16/double, until I realized you must use "double" instead of "uint16".

Here are some useful definitions:

uint8: Is 8 bit, or one Byte. 0 to 255 (0 black, 255 white).

uint16
: Is 16 bits or 2 Bytes. 0 to 65535 or -32766 to 32766 something, not sure here.

Single: (src. wiki) Single precision is a computer numbering format that occupies one storage location in computer memory at a given address. A single-precision number, sometimes simply a single, may be defined to be an integer, fixed point, or floating point.

Double: (src. wiki) Double precision is a computer numbering format that occupies two adjacent storage locations in computer memory. A double precision number, sometimes simply called a double, may be defined to be an integer, fixed point, or floating point.

The solution:

I came to know that there are two ways to designate gray scale images. uint8 and double. The difference; double is more precise since it uses "fraction, or decimal point" to display white to black gradient (0 to 1) instead of the uint8 method of 0 to 255 levels. Plus, "double" uses 64-bit storage to represent the fraction, much more accurate than 32-bit storage of "single" precision.

So now you know, use double instead of uint16. Where do you apply that?

In the original post its stated that you are receiving your images from a video source. If it is a webcam I think the problem can be solved.:

start(vid); %vid is the video object
mov = avifile('MOVIE.avi','compression','None') %your movie file object, use whatever compression.
while(vid.FramesAcquired<=100) % Loop to capture rectangular area and video from source and store frames in MOVIE.avi. Stop after 100 frames.
imgrgb = getdata(vid,1,'double'); %!IMPORTANT! Get data from video source of "double" precision. Original image in Color(RGB).
I =.2989*imgrgb😀,:,1)+.5870*imgrgb😀,:,2)+.1140*imgrgb😀,:,3); % Convert to grayscale, *SEE NOTE AT END!!

%

mov = addframe(mov,I_withRect);
end

%% Garbage clearance
stop(vid);
mov = close(mov);



* NOTE: My algorithm is the same as "im2gray"[help[LINK]] uses, The grayscale image will be of original "double" precision, which can be easily sent to "addframe()" function, as the help stated, it will accept "double" and "uint8"!


Let me tell you, I could not write an AVI file with any program on my PC, which must be because of some problem with compression and not related to this.

Hope I was of help.
prestonee
prestonee • Aug 15, 2008
Sorry I have not replied I have been busy with an end of project report as well demonstrating the matlab processing file to various people on my side. Currently the system is working at 100% except for this 16b to 8b part which is a fairly low priority since this is just a visual assurance that the processing is occuring. I will try to convert the image files to double on monday and get back to you. I wouldnt expect an increase in visibility since we cant take advantage of any information stored on the right side of the decimal. But will try it and reply
xheavenlyx
xheavenlyx • Aug 17, 2008
Yea, thats fine, ive been off too.

To analyze data "on the right side of the decimal" is not a problem in MATLAB. It does the calculations to many many many significant digit. Otherwise decimal would not have existed in MATLAB if it couldn't "take advantage of it".

And, anyway, if you are storing the data as AVI, compression will of course reduce visibility. Plus, AVI is designed to work with 8bit and double ONLY, not 16 bit. And double is a standard for black and white images. (Read that somewhere on Image possessing article from Adobe.)

I hope you have read the whole post, there are a lot of surprising new details that are new even to me.

Share this content on your social channels -