accessing and changing manually, pixels data for a 3 channels opencv image

Hi,

I tried to set the value of pixels to null for an image (frame_copy)  if the both compared images (frame_copy and frame) that are coming from video capture are the same data.

You will understand the goal is to substract the background.
here below the code.

The program crashs in the function diff_pix(),  I do wrong something, could you help me ?

Thank you



#include <stdlib.h>
#include <stdio.h>
#include <cv.h>
#include <cvaux.h>
#include <highgui.h>


 diff_pix(IplImage* image, IplImage* frame)
{
     
      int nl= image->height; // number of lines
      int nc= image->width * image->nChannels; // total number of element per line
      int step= image->widthStep; // effective width

      // get the pointer to the image buffer
      unsigned char *data= reinterpret_cast<unsigned char *>(image->imageData);
      unsigned char *dataframe= reinterpret_cast<unsigned char *>(frame->imageData);

      for (int i=1; i<nl; i++) {
            for (int j=0; j<nc; j++/*= image->nChannels*/) {

				 int pos = i * j /*+ j*image->nChannels*/;

				  if( data[pos] == dataframe[pos])
				  {
                  data[pos]= 0;
				  }
				  if( data[pos+1] == dataframe[pos+1])
				  {
                  data[pos+1]= 0;
				  }
				  if( data[pos+2] == dataframe[pos+2])
				  {
                  data[pos+2]= 0;
				  }

            } // end of line
            
        data+= step;  // next line
		dataframe+=step;
      }

}


int main()
{
	IplImage* test=0;
	CvCapture* capture = 0;

	capture   = cvCaptureFromAVI("C:\\vga.avi");

    double num_frames = 0, t = 0;
	cvNamedWindow("contours", 0);

	if(capture)
	{
		test = cvQueryFrame(capture);
		int width = (int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH );
		int height= (int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT);
		printf("width %d height %d\n",width,height);
		
		IplImage* frame    = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U  ,3);
		IplImage* frame_copy = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U  ,3);
		IplImage* gray     = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U  ,1);
		IplImage* gaussian = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U  ,1);

		bool flip = true;
		while(cvGrabFrame(capture)) 
		{
			//cvSetCaptureProperty(capture, CV_CAP_PROP_POS_AVI_RATIO, (double)3.0);
			frame = cvRetrieveFrame(capture);
			cvNamedWindow("Capture Webcam", 0);
			cvShowImage("Capture Webcam",frame);
			cvWaitKey(20);

			if( !frame_copy )
			{
				// first time in this loop
				frame_copy = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 3 );
				t = (double)cvGetTickCount();
			}

			diff_pix(frame_copy,frame);
			cvShowImage("contours", frame_copy);
			cvWaitKey(20);
			
			num_frames++;
			//cvCopy(frame, frame_copy);
			cvCopy(frame_copy,frame);
			//cvShowImage("contours", frame_copy);

		}
	}
	else printf("Video stream not found\n\n");
	return 0;
}

Open in new window

DevelprogAsked:
Who is Participating?
 
Infinity08Commented:
>> but the same problem persists and each seconds more or minus the image changes for a very short instant like (video_sequence_changes) it sems like image background changes or refresh his self each seconds or i don't know what happen?

This sounds a lot like (lossy) video compression (DivX or something similar). If you could find a way to record a video without compression (or use a lossless compression instead), these issues should disappear.
To verify this, you could use a tool like GSpot to find out which codec (and compression) was used for the video.
0
 
Infinity08Commented:
Try :

                                 int pos = (i * nc) + (j * image->nChannels);

instead of :

>>                                  int pos = i * j /*+ j*image->nChannels*/;

0
 
Infinity08Commented:
Oh, wait - your upper limit for the loop is different, so make that :
 diff_pix(IplImage* image, IplImage* frame)
{
     
      int nl= image->height; // number of lines
      int nc= image->width * image->nChannels; // total number of element per line
      int step= image->widthStep; // effective width

      // get the pointer to the image buffer
      unsigned char *data= reinterpret_cast<unsigned char *>(image->imageData);
      unsigned char *dataframe= reinterpret_cast<unsigned char *>(frame->imageData);

      for (int i=1; i<nl; i++) {
            for (int j=0; j<nc; j += image->nChannels) {

                                 int pos = (i * step) + j;

                                  if( data[pos] == dataframe[pos])
                                  {
                  data[pos]= 0;
                                  }
                                  if( data[pos+1] == dataframe[pos+1])
                                  {
                  data[pos+1]= 0;
                                  }
                                  if( data[pos+2] == dataframe[pos+2])
                                  {
                  data[pos+2]= 0;
                                  }

            } // end of line
            
      }

}

Open in new window

0
Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

 
itsmeandnobodyelseCommented:
>>> int pos = (i * step) + j;

I would do (and forget the step completely).

  int pos = (i*nc) + j;

or use other loop boundaries if that is wrong.

   
0
 
Infinity08Commented:
>> I would do (and forget the step completely).

But that's incorrect. The width of a line is image->widthStep (ie. step), not (image->width * image->nChannels). There might be padding at the end of the line, which is precisely why the step exists.
0
 
DevelprogAuthor Commented:
Hi,

The  crash issue was coming from these lines:

        //data+= step;  // next line  ////
      //dataframe+=step;

Now the program doesn't crash but the result is strange because when the pixels are same
I want to change color to white (by setting data to 255) so frame_copy must have white background and on foreground  the normal colored moving person from the example here.
And what I have is here below on image for the code below.

The background color is black and there is no update of frame_copy,
no substraction because all changed background pixels don't take their old color
(black in this case) why ?
 
how do it  to force rgb color to white  and update the background.        ?


Thank you

diff_pix(IplImage* image, IplImage* frame)
{
     
      int nl= image->height; // number of lines
      int nc= image->width * image->nChannels; // total number of element per line
      int step= image->widthStep; // effective width

      // get the pointer to the image buffer
      unsigned char *data= reinterpret_cast<unsigned char *>(image->imageData);
      unsigned char *dataframe= reinterpret_cast<unsigned char *>(frame->imageData);

      for (int i=1; i<nl; i++) {
            for (int j=0; j<nc; /*j++ */ j += image->nChannels) {

				int pos = (i * step) + j;

				  if( data[pos] == dataframe[pos])
				  {

                  data[pos]= 255;

				  }
				  if( data[pos+1] == dataframe[pos+1])
				  {

                   data[pos+1]= 255;

				  }
				  if( data[pos+2] == dataframe[pos+2])
				  {

                  data[pos+2]= 255;

				  }

            } // end of line
           
        //data+= step;  // next line  ////
		//dataframe+=step;            ////
      }
}


int main()
{
	IplImage* test=0;
	CvCapture* capture = 0;

capture   = cvCaptureFromAVI("C:\\video4.avi");

    double num_frames = 0, t = 0;
//	cvNamedWindow("contours", 0);

	if(capture)
	{
		test = cvQueryFrame(capture);
		int width = (int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH );
		int height= (int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT);
		printf("width %d height %d\n",width,height);
		
		IplImage* frame    = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U  ,3);
		IplImage* frame_copy = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U  ,3);
		IplImage* gray     = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U  ,1);
		IplImage* gaussian = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U  ,1);

		bool flip = true;
		while(cvGrabFrame(capture)) 
		{
			frame = cvRetrieveFrame(capture);
			cvNamedWindow("Capture Webcam", 0);
			cvNamedWindow("contours", 0);////

			cvShowImage("Capture Webcam",frame);
			cvWaitKey(20);

			cvFlip(frame, NULL, 0);////

			//test background
			if( !frame_copy )
			{
				// first time in this loop
				frame_copy = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 3 );
				t = (double)cvGetTickCount();
			}

			diff_pix(frame_copy,frame);
			cvShowImage("contours", frame_copy);
			cvWaitKey(20);
			
			num_frames++;
			//cvCopy(frame, frame_copy);
			cvCopy(frame_copy,frame);
			//cvShowImage("contours", frame_copy);

		}
	}
	else printf("Video stream not found\n\n");
	return 0;
}

Open in new window

test-video-background.bmp
0
 
Infinity08Commented:
>> Now the program doesn't crash but the result is strange because when the pixels are same
>> I want to change color to white (by setting data to 255)

Did you mean the code below ?

If the pixel has the same color in both images, it's set to white. Otherwise, it's not modified :
if ((data[pos] == dataframe[pos]) && (data[pos+1] == dataframe[pos+1]) && (data[pos+2] == dataframe[pos+2])) {
    data[pos] = 255;
    data[pos+1] = 255;
    data[pos+2] = 255;
}

Open in new window

0
 
DevelprogAuthor Commented:
Yes but with this code ( you posted in ID 30801591)  the program doesn't work better than before.
because the program that works here below doesn't work when I add this segment of code.

For the update problem I fix it by only adding a release of the image "frame_copy".
The problem seems to come if the image data has too many colors.

But pay attention that this update problem stay when ther is too many activities on the video, and especially for the previous video I posted the update of the flowers works very nice till the person entrance on image after this moment update does'n't work no more for flowers and for person, strange isn't it ?

Her below the program works very well with a simple fake video at 5 fps (see code and image)
but you can see there is still problem  to obtain the white color and why green color instead of ?
 

Thank you
diff_pix(IplImage* image, IplImage* frame)
{
     
      int nl= image->height; // number of lines
      int nc= image->width * image->nChannels; // total number of element per line
      int step= image->widthStep; // effective width

      // get the pointer to the image buffer
      unsigned char *data= reinterpret_cast<unsigned char *>(image->imageData);
      unsigned char *dataframe= reinterpret_cast<unsigned char *>(frame->imageData);


      for (int i=1; i<nl; i++) {
            for (int j=0; j<nc; /*j++ */j += image->nChannels) {


				int pos = (i * step) + j;

				  if( data[pos] == dataframe[pos])
				  {

                  data[pos]= 0xFF;

				  }
				  if( data[pos+1] == dataframe[pos+1])
				  {

                   data[pos+1]= 0xFF;

				  }
				  if( data[pos+2] == dataframe[pos+2])
				  {

                  data[pos+2]= 0xFF;

				  }
				  
				  
/*
				  if( (data[pos] == dataframe[pos]) && (data[pos+1] == dataframe[pos+1]) && (data[pos+2] == dataframe[pos+2]))
				  {
					    data[pos] = 255;
					    data[pos+1] = 255;
						data[pos+2] = 255;
				  }
*/
            } // end of line

           
        //data+= step;  // next line  ////
		//dataframe+=step;            ////

      }
}


int main()
{
	IplImage* test=0;
	CvCapture* capture = 0;

capture   = cvCaptureFromAVI("C:\\video_small_collision.avi");


    double num_frames = 0, t = 0;
//	cvNamedWindow("contours", 0);

	if(capture)
	{
		test = cvQueryFrame(capture);
		int width = (int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH );
		int height= (int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT);
		printf("width %d height %d\n",width,height);
		
		IplImage* frame    = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U  ,3);
		IplImage* frame_copy = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U  ,3);
		IplImage* gray     = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U  ,1);
		IplImage* gaussian = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U  ,1);

		bool flip = true;
		while(cvGrabFrame(capture)) 
		{

			frame = cvRetrieveFrame(capture);
			cvNamedWindow("Capture Webcam", 0);
			cvNamedWindow("contours", 0);////

			cvShowImage("Capture Webcam",frame);
			cvWaitKey(20);

			cvFlip(frame, NULL, 0);////
			
			//test background
			if( !frame_copy )
			{
				// first time in this loop
				frame_copy = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 3 );
				t = (double)cvGetTickCount();
			}

			diff_pix(frame_copy,frame);
			cvShowImage("contours", frame_copy);
			cvWaitKey(1);
			
			num_frames++;
			//cvCopy(frame, frame_copy);
			cvCopy(frame_copy,frame);
			//cvShowImage("contours", frame_copy);
			cvReleaseImage(&frame_copy);
		}
	}
	else printf("Video stream not found\n\n");
	return 0;
}

Open in new window

test-video-background-fake.bmp
0
 
Infinity08Commented:
>> because the program that works here below doesn't work when I add this segment of code.

You don't need to add it - you need to replace the three existing if's with the one if I posted.


>> but you can see there is still problem  to obtain the white color and why green color instead of ?

That is likely because you still have the three if's, instead of the one if that I suggested.


If the point is for anything that hasn't changed to become white, and anything that has changed to stay the original color, then that's what the if I posted does.

If you want different behavior, then please describe exactly how you would like the diff to work.
0
 
DevelprogAuthor Commented:

>>You don't need to add it - you need to replace the three existing if's with the one if I posted.

I tested by replacing my code with your with the both videos.
Now strangly the movements around flowers can't be displayed but the person can be displayed.

For the simple video the results is a black image video when I test with the simple fake video

 (pls see images image_code_normal, image_code_simple)?  

>>If the point is for anything that hasn't changed to become white, and anything that has
>>changed to stay the original color, then that's what the if I posted does.

Yes I need exactly what you mention here, it is almost  background substraction

Thank you
diff_pix(IplImage* image, IplImage* frame)
{
     
      int nl= image->height; // number of lines
      int nc= image->width * image->nChannels; // total number of element per line
      int step= image->widthStep; // effective width

      // get the pointer to the image buffer
      unsigned char *data= reinterpret_cast<unsigned char *>(image->imageData);
      unsigned char *dataframe= reinterpret_cast<unsigned char *>(frame->imageData);


      for (int i=1; i<nl; i++) {
            for (int j=0; j<nc; /*j++ */j += image->nChannels) {


				int pos = (i * step) + j;

				  if( (data[pos] == dataframe[pos]) && (data[pos+1] == dataframe[pos+1]) && (data[pos+2] == dataframe[pos+2]))
				  {
					    data[pos] = 255;
					    data[pos+1] = 255;
						data[pos+2] = 255;
				  }

            } // end of line

           
        //data+= step;  // next line  ////
		//dataframe+=step;            ////

      }
}


int main()
{
	IplImage* test=0;
	CvCapture* capture = 0;

if(normal)
capture   = cvCaptureFromAVI("C:\\video4.avi");
else
capture   = cvCaptureFromAVI("C:\\video_small_collision.avi");

    double num_frames = 0, t = 0;
//	cvNamedWindow("contours", 0);

	if(capture)
	{
		test = cvQueryFrame(capture);
		int width = (int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH );
		int height= (int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT);
		printf("width %d height %d\n",width,height);
		
		IplImage* frame    = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U  ,3);
		IplImage* frame_copy = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U  ,3);
		IplImage* gray     = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U  ,1);
		IplImage* gaussian = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U  ,1);

		bool flip = true;
		while(cvGrabFrame(capture)) 
		{

			frame = cvRetrieveFrame(capture);
			cvNamedWindow("Capture Webcam", 0);
			cvNamedWindow("contours", 0);////

			cvShowImage("Capture Webcam",frame);
			cvWaitKey(20);

			cvFlip(frame, NULL, 0);////
			
			//test background
			if( !frame_copy )
			{
				// first time in this loop
				frame_copy = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 3 );
				t = (double)cvGetTickCount();
			}

			diff_pix(frame_copy,frame);
			cvShowImage("contours", frame_copy);
			cvWaitKey(1);
			
			num_frames++;
			//cvCopy(frame, frame_copy);
			cvCopy(frame_copy,frame);
			//cvShowImage("contours", frame_copy);
			cvReleaseImage(&frame_copy);
		}
	}
	else printf("Video stream not found\n\n");
	return 0;
}

Open in new window

image-code-normal.JPG
image-code-simple.JPG
0
 
Infinity08Commented:
At the end of the while loop, you call cvCopy like this :

>>                   cvCopy(frame_copy,frame);

that would copy frame_copy into frame. That's not what you want. You want to copy frame into frame_copy, so :

                  cvCopy(frame, frame_copy);

You also don't want to release it like you do here :

>>                   cvReleaseImage(&frame_copy);

You want to keep the frame_copy around for the entire duration of the loop (as a copy of the previous frame). So something like :
		frame_copy = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 3);
		t = (double) cvGetTickCount();

		cvNamedWindow("Capture Webcam", 0);
		cvNamedWindow("contours", 0);

		while (cvGrabFrame(capture))
		{
			frame = cvRetrieveFrame(capture);

			cvShowImage("Capture Webcam", frame);
			cvWaitKey(20);

			//cvFlip(frame, NULL, 0);                // <--- DO YOU NEED THIS ????

			diff_pix(frame_copy, frame);
			cvShowImage("contours", frame_copy);
			cvWaitKey(1);
			
			num_frames++;
			cvCopy(frame, frame_copy);
		}

		cvReleaseImage(&frame_copy);

Open in new window

0
 
DevelprogAuthor Commented:

Yes, now the code works well, but the background substraction is very sensitive
so why the resulting image is not very stable,  thing that I don't understand, this is periodically changing the white pixels rate in the image (see the 2 images  normal_background_white_high.JPG & normal_background_white_low.JPG)

Another thing, when the person move slowly ( the head) we can see that there are white pixels. (pls see image normal_background_white.JPG). So maybe must I use blobs or contour detection to subtract background with foreground ?

So is not good way to do background substraction isn't it ? Must I add contour detection or review the current code to access at a different rate to the pixels or maybe by changing threshold values ?

Thank you

#include <stdlib.h>
#include <stdio.h>
#include <cv.h>
#include <cvaux.h>
#include <highgui.h>



 diff_pix(IplImage* image, IplImage* frame)
{
     
      int nl= image->height; // number of lines
      int nc= image->width * image->nChannels; // total number of element per line
      int step= image->widthStep; // effective width

      // get the pointer to the image buffer
      unsigned char *data= reinterpret_cast<unsigned char *>(image->imageData);
      unsigned char *dataframe= reinterpret_cast<unsigned char *>(frame->imageData);


      for (int i=1; i<nl; i++) {
            for (int j=0; j<nc; j++ /*j += image->nChannels*/) {
		
				//int pos = (i*nc) + j;
				int pos = (i * step) + j;

				  if( (data[pos] == dataframe[pos]) && (data[pos+1] == dataframe[pos+1]) && (data[pos+2] == dataframe[pos+2]))
				  {
					    data[pos] = 255;
					    data[pos+1] = 255;
						data[pos+2] = 255;
				  }

            } // end of line

      }
}


int main()
{
	IplImage* test=0;
	CvCapture* capture = 0;

capture   = cvCaptureFromAVI("video4.avi");

    double num_frames = 0, t = 0;


	if(capture)
	{
		test = cvQueryFrame(capture);
		int width = (int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH );
		int height= (int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT);
		printf("width %d height %d\n",width,height);
		
		IplImage* frame    = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U  ,3);
		IplImage* frame_copy = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U  ,3);
		IplImage* gray     = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U  ,1);
		IplImage* gaussian = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U  ,1);


		frame_copy = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 3 );
		t = (double)cvGetTickCount();
		cvNamedWindow("Capture Webcam", 0);
		cvNamedWindow("contours", 0);

		bool flip = true;
		while(cvGrabFrame(capture)) 
		{

			frame = cvRetrieveFrame(capture);

			cvShowImage("Capture Webcam",frame);
			cvWaitKey(20);

			cvFlip(frame, NULL, 0);////

			diff_pix(frame_copy,frame);
			cvShowImage("contours", frame_copy);
			cvWaitKey(50);
			
			num_frames++;
			cvCopy(frame, frame_copy);

			
		}
		cvReleaseImage(&frame_copy);
	}
	else printf("Video stream not found\n\n");
	return 0;
}

Open in new window

normal-background-white.JPG
normal-background-white-high.JPG
normal-background-white-low.JPG
0
 
Infinity08Commented:
First of all : try removing the cvFlip like I suggested earlier. I don't think you need it.


>> Yes, now the code works well, but the background substraction is very sensitive

Well, you're comparing pixel-by-pixel, and whenever a pixel is different, it's seen as movement.

If you're detecting too much movement, you could try using a threshold like you said (ie. only see it as a change if the color changed more than x amount).

Or you could check neighboring pixels, and only see it as a change if x pixels around it changed too.


Just a question : the garden scene : is that a static image ? Or is it dynamic ? You should probably try with a static image, just to see if the diff works as it should (ie. it should detect no change at all).

Another thing of note, in case it's a movie - try disabling compression.
0
 
DevelprogAuthor Commented:
>>First of all : try removing the cvFlip like I suggested earlier. I don't think you need it.

but when I remove this line,  the copy_frame is flipped I don't know why ?
(see below image)


I will try with treshold, but I don't think that it will resolve this issue in ID: 30921932:
"Another thing, when the person move slowly ( the head) we can see that there are white pixels. (pls see image normal_background_white.JPG). So maybe must I use blobs or contour detection to subtract background with foreground ?"

What algortihm or function that needs to resolve this issue ?

Thank you

without-flip.JPG
0
 
Infinity08Commented:
>> but when I remove this line,  the copy_frame is flipped I don't know why ?

Ok. Understood. It means the input from the webcam (or whichever input you're using) is flipped.


Could you please answer this question ?

>> Just a question : the garden scene : is that a static image ? Or is it dynamic ? You should probably try with a static image, just to see if the diff works as it should (ie. it should detect no change at all).
0
 
DevelprogAuthor Commented:

>>Could you please answer this question ?
In fact the image is not really static because of wind on trees and flowers,...

Here I test it with a more static background video see images below and like you can see
diff works as it should if considering  (video_sequence) but the same problem persists and each seconds more or minus the image changes for a very short instant like (video_sequence_changes) it sems like image background changes or refresh his self each seconds or i don't know what happen?

thank you




 


video-sequence.JPG
video-sequence-changes.JPG
0
 
DevelprogAuthor Commented:

>>Ok. Understood. It means the input from the webcam (or whichever input you're using) is flipped.
But you can see that the original image is not flipped but the frame_copy is.

So with the code below (without the flip instruction)  the output images are these of  ID: 31061930.
There is something other ?

Thank you


		frame_copy = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 3 );
		t = (double)cvGetTickCount();
		cvNamedWindow("Capture Webcam", 0);
		cvNamedWindow("contours", 0);

		while(cvGrabFrame(capture)) 
		{

			frame = cvRetrieveFrame(capture);

			cvShowImage("Capture Webcam",frame);
			cvWaitKey(20);

			//cvFlip(frame, NULL, 0);////

			diff_pix(frame_copy,frame);
			cvShowImage("contours", frame_copy);
			cvWaitKey(50);
			
			num_frames++;
			cvCopy(frame, frame_copy);

			
		}
		cvReleaseImage(&frame_copy);

Open in new window

0
 
DevelprogAuthor Commented:
Right,

Seems that is codec problem I will chek it with gspot.
Otherwhise with a capture function with opencv from stream of a webcam.
the direct captured stream from a webcam is not compressed isn't it ?


Concerning the flipped image,  why this events occurs,  seems like diff_pix() do a flip or spmething that  ?

 




0
 
Infinity08Commented:
>> Seems that is codec problem I will chek it with gspot.

What you describe, fits with video compression. Let me know if that turns out to be the case.


>> the direct captured stream from a webcam is not compressed isn't it ?

It probably is. Especially if you compare the bandwidth needed for an uncompressed and a compressed stream (it could be a difference of several orders of magnitude).


>> Concerning the flipped image,  why this events occurs,  seems like diff_pix() do a flip or spmething that  ?

No. But the original image (frame) is probably flipped, and has its origin set to the bottom left, while the copied image (frame_copy) has its origin set to the top left.

By simply setting the origin of frame_copy correctly (before calling diff_pix), the cvFlip should not be needed :

        frame_copy->origin = frame->origin;
0
 
DevelprogAuthor Commented:


The video forma
0
 
DevelprogAuthor Commented:
>>By simply setting the origin of frame_copy correctly (before calling diff_pix), the cvFlip should not be
Yes that fixes this issue.

The gspot out for this video sequencet is :
  - FFmpeg/ffdshow ISO MPEG-4 (codec are not installed)
  - 640x240

So with virtualdub I change it  to :  -  BI_RGB Raw Bitmap ( No codec required)

After the test give the same issue each second, seems that this is not du to compression?

Thank you
0
 
Infinity08Commented:
>> After the test give the same issue each second, seems that this is not du to compression?

Since you converted the compressed video to a non-compressed one, the same compression artifacts are converted with it - so the result will indeed be the same.

The idea is to record a new video without compression.
0
 
DevelprogAuthor Commented:

How would it be if we extract from the video stream image files and save it to ppm or pgm file type?

So the program will load image files instead of video stream, with this method
compression artifacts will still persist in the image file ?

Thank you


 
0
 
Infinity08Commented:
If the video stream is compressed, then everything you get out of it will show those same compression artifacts.

Do you have a way to record a new uncompressed avi ? (with a digital camera eg.)
0
 
DevelprogAuthor Commented:
Yes,

I have a digital camera (Sanyo)  but the output are .mp4 files.
Gspot gives :  H.264/MPEG-4 AVC (Codec Status Undetermined)

If I good understood I need  .raw file for image and for video a container (.avi or .mpeg or .mov) whih would be not compressed isn't it?

So is there a way with a camera digital to have an non compressed output ?

Thank you



0
 
Infinity08Commented:
>> If I good understood I need  .raw file for image and for video a container (.avi or .mpeg or .mov) whih would be not compressed isn't it?

Uncompressed or compressed with a lossless compression algorithm. Both should be fine.


>> So is there a way with a camera digital to have an non compressed output ?

You'll have to check the manual for your camera.

Uncompressed video samples are quite rare on the internet, but a quick search turned up these :

        ftp://ftp.crc.ca/crc/vqeg/TestSequences/
        http://www.hdgreetings.com/other/ecards-video/video-1080p.aspx

They might be useful.
0
 
DevelprogAuthor Commented:
ok I have an yuv file video but Opencv can't read it.
the function cvCaptureFromAVI gives: video stream not found

Is ther a way to read this file with opencv?

thank you
0
 
Infinity08Commented:
Convert it to a format that is readable by OpenCV ;) Can't give you more specific help than that though heh.

In any case, I think we've strayed quite far from the original question now ;)
0
 
DevelprogAuthor Commented:

Yes you are right about the question evolution  ;).
 
But concerning the conversion  I tried to use Xilisoft converter but it doesn't work and try to read on of them .yuv file with VLC and video is played but like seems to be cryptted or I don't know but anyway I found another video (Compression FFDS)  wich one that works well so the problem was well on compression.

Just one last question :). Is it normal that the size of this video 620x480 is not displayed but it becomes 305x280 on Opencv window. And this happens for all video the original size is not displayed is this maybe automatic adapted Opencv window size ?


Thank you
0
 
Infinity08Commented:
>> but anyway I found another video (Compression FFDS)  wich one that works well so the problem was well on compression.

Great :)


>> Is it normal that the size of this video 620x480 is not displayed but it becomes 305x280 on Opencv window. And this happens for all video the original size is not displayed is this maybe automatic adapted Opencv window size ?

Do you mean that the following shows the wrong size ?

>>             int width = (int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH );
>>             int height= (int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT);
>>             printf("width %d height %d\n",width,height);
0
 
DevelprogAuthor Commented:

Yes,

for example for another video
the printf gives
"width 384 height 288"

but when I measure pixels of opencv windows with a cool soft PixelRuler
width = 304
height = 208

So there is difference of 80 pixels fot this video ?

Thank you

0
 
Infinity08Commented:
I don't know what would cause that.
0
 
DevelprogAuthor Commented:
Thank you anyway,

But for this little issue it was my fault, after that I change parameter of Opencv to initialize the window by autosizing to the image size so put "1" instead of "0" and it resolves  :) .

So the  question is now closed, although the real was closed before.
Thank you for your help







0
 
Infinity08Commented:
>> to initialize the window by autosizing to the image size so put "1" instead of "0" and it resolves  :) .

Heh :) Seems I missed that in your code lol.
0
 
DevelprogAuthor Commented:

we don't think to small things sometimes :)




0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.