How to show an image saved in runtime at a matrix as a video?

Hi, all, i have a problem with this script that doesn't do what a need to; i'm getting initiated in Matlab, so i'm waiting you to support me for. I'll be very grateful.
The code is:
_____________________________________________________
function videomonocolor
vid = videoinput('macvideo', 1, 'YCbCr422_1280x720');
k=0;
c=1;
start(vid);
while c<100
A = getsnapshot(vid);
A=imresize(A,0.3);
rgb = A;
I = ycbcr2rgb(rgb);
imshow(I)
c=c+1;
end
end
__________________________________________________________
As You can see, the script is very austere; then well, what im trying to do is take a snapshot from my macbook's camera and give it to a matrix that could be modified, saving, so, all informatión of image, then work with it, and display it again. All this have a purpose, but now, I just have one problem: the imshow doesn't show me anything. Some times show just the last image that was taken, when the program it's done. I think isn't the appropriate way to display every image and show almost at runtime, just like a video motion. I don't want to take a sequence of photos, then use the comand that convert this same sequence to a video. I want to work with an image at the time, and show the same information that has been token. I know about the function that do this, showing a preview of the video.. but i want every snapshot for do something with it... I apologise for my english, that is not the best. Greetings from México, and good night here.

Answers (2)

The badly-named I is probably a double and imshow doesn't like RGB doubles. Cast it to uint8 and it will probably be okay. But a worse problem is that you're possibly taking an RGB image and passing it in to ycbcr2rgb() which expects an input that is of YCbCr color space, not RGB color space. If you call imshow(A), does it look like a normally colored image? If so why are you even calling ycbcr2rgb() since A is already RGB?
How do you make sure the badly-named A is an RGB image? Well after you instantiate vid you have to set the returned color space:
vid.ReturnedColorSpace = 'rgb';

12 Comments

I have now modified some things and it works... No, you're almost wrong, in the part: I = ycbcr2rgb(rgb); i'm changing the format of the snapshot, because my laptop have only one unchangeable default values, that one of them is the default .ycbcr format. You can check it from this line:
vid = videoinput('macvideo', 1, 'YCbCr422_1280x720');
The thing that I did want to say, is that I like to show only one color of the video, and already have done.
The code is the next:
________________________________________________
function videomonocolor
vid = videoinput('macvideo', 1, 'YCbCr422_1280x720'); k=0; c=1;
preview(vid);
for n=1:100
A = getsnapshot(vid); A=imresize(A,0.3); rgb = A; I = ycbcr2rgb(rgb);
[r, c, l]=size(I);
for i=1:r for j=1:c
if (((I(i,j,2)<0 && I(i,j,3)<150 && I(i,j,1)<50)))
kkkk=0;
else
I(i,j,1)=0;
I(i,j,2)=0;
I(i,j,3)=0;
%I(i,j,1)=0;
%I(i,j,3)=0;
%I(i,j,2)=0;
end
end
end
imshow(I); drawnow
c=c+1;
end
end
_________________________________________
Thank you for all :')
But since your camera returns YCbCr, and you didn't change the returned color space with the line I suggested
vid.ReturnedColorSpace = 'rgb';
Then A is YCbCr, and despite the fact that you do this:
rgb = A
does not mean rgb is an RGB image. It's the same as A which is YCbCr. When you do
I = ycbcr2rgb(rgb);
you're passing a YCbCr image into ycbcr2rgb(), which doesn't make sense (to me).
I don't know the purpose of your loop. Why is the if there? Why does showing only one color channel depend on what the values of it are? Why not just set two of the planes to zero. And why are you using a for loop instead of vectorizing it? And what is the point of the kkk variable?
Oh well, whatever - if you're happy with it that's all that counts. If you need anymore advice, let me know. I use the Image Acquisition Toolbox all the time.
I think you don't realize what's happening. Let me rename some variables and then I think you might understand better:
YCbCrImage = getsnapshot(vid);
YCbCrImage = imresize(YCbCrImage,0.3);
rgbImage = ycbcr2rgb(YCbCrImage);
Now, get rid of that double for loop and do this:
% Get mask with low green and red signals and high blue signal.
mask = rgbImage(i,j,2)<30 && rgbImage(i,j,3)>150 && rgbImage(i,j,1)<50
% Mask the original image with this:
% Mask the image using bsxfun() function
maskedRgbImage = bsxfun(@times, rgbImage, cast(mask, class(rgbImage)));
% Display is
imshow(maskedRgbImage);
And you don't need c or kkk, and you don't need to call size().
I really thank you for all that, you have the reason, i did what you mentioned there, and I had the same result but without all that thing. Nor even knew about those Matlab's functions.
Good night :')
Oh, about the kkk variable, I just put it there for do not leave anything in that If condition, hahahaha, sorry for all.
You're welcome. If we're done here, then can you officially mark the answer as "Accepted". Thanks in advance.
Of course, just after tell you why I get all that into a For function: I want to check every pixel token from my video camera, verify that the color is one chosen by me and then, if isn't, change it to black... at the first; then, i want to change that same pixel, and give it a pixel from another image with that same size... So, I can do not allow, for example, the color green, and leave the rest, to change just the background with a green blanked. I know, is a dumb thing, but i really want to make it :)
You have your "for" loop over n, where you do this for 100 frames, and I guess that will stay, though you might want to increase it some to allow for a longer video. And like I said, you don't need the for loop over i and j anymore because I gave you vectorized code that operates on the whole image at once. No need to scan every single pixel in the image like you were doing. It's all done with two fast lines of code:
mask = rgbImage(i,j,2)<30 && rgbImage(i,j,3)>150 && rgbImage(i,j,1)<50
maskedRgbImage = bsxfun(@times, rgbImage, cast(mask, class(rgbImage)));
You have your "for" loop over n, where you do this for 100 frames, and I guess that will stay, though you might want to increase it some to allow for a longer video. And like I said, you don't need the for loop over i and j anymore because I gave you vectorized code that operates on the whole image at once. No need to scan every single pixel in the image like you were doing. It's all done with two fast lines of code:
mask = rgbImage(i,j,2)<30 && rgbImage(i,j,3)>150 && rgbImage(i,j,1)<50
maskedRgbImage = bsxfun(@times, rgbImage, cast(mask, class(rgbImage)));
Yeah, indeed, but then, how can i change the pixels that do not are a scale of blue indeed another image? I mean, superimpose one image upon the pixel of other...
See my attached demo where I track a green sharpie in a video. Just follow my example.
Thanks for the script, and all the support. I'll work on it :')

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!