Ask Your Question

How to copy frames read by videoCapture

asked 2019-10-30 13:25:39 -0500

TakiEddine gravatar image

I"m trying to use the OpenCV VideoCapture class to read images sequentially from a specific folder, as shown in the code below, which is extracted from The reading works just fine and I can view the video streaming of the read images (imgSrc) correctly. The problem happens when I try to copy each frame into a new Mat object using nested for loops, the new image (imgDst) is different from the original one. I attached the results of the frame below. I did try using image.clone() and it worked perfectly, however, it is not an option for me, as I need to read the image on a pixel-by-pixel basis. Is there anything I am doing wrong so that I get this weird result? I'm reading 16 bit png images, but I assume that the VideoCapture is changing this in some way, could this really be the issue ?

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;

void help(char** argv)
cout << "\nThis program gets you started reading a sequence of images using cv::VideoCapture.\n"
     << "Image sequences are a common way to distribute video data sets for computer vision.\n"
     << "Usage: " << argv[0] << " <path to the first image in the sequence>\n"
     << "example: " << argv[0] << " right%%02d.jpg\n"
     << "q,Q,esc -- quit\n"
     << "\tThis is a starter sample, to get you up and going in a copy paste fashion\n"
     << endl;

int main(int argc, char** argv)
if(argc != 2)
  return 1;

string arg = argv[1];
VideoCapture sequence(arg);
if (!sequence.isOpened())
  cerr << "Failed to open Image Sequence!\n" << endl;
  return 1;

Mat imgSrc; // source image
  sequence >> imgSrc;

      cout << "End of Sequence" << endl;
  Mat imgDst = cv::Mat::zeros(cv::Size(imgSrc.size().width,imgSrc.size().height),CV_16U);

  // Copying the elements of imgSrc to imgDst
  uint16_t* imgSrcPtr;
  uint16_t* imgDstPtr;
  for(int i = 0; i < imgSrc.rows; i++)
      imgDstPtr = imgDst.ptr<uint16_t>(i);
      imgSrcPtr = imgSrc.ptr<uint16_t>(i);

       for(int j= 0; j < imgSrc.cols; j++)
       imgDstPtr[j] = imgSrcPtr[j];

  namedWindow("Source image ",WINDOW_AUTOSIZE );

  namedWindow("Destination image ",WINDOW_AUTOSIZE );
  imshow("Destination image ", imgDst);

return 0;

Source image Destination image

edit retag flag offensive close merge delete


please check imgSrc.type()

berak gravatar imageberak ( 2019-10-30 13:34:35 -0500 )edit

the output of imgSrc.type() at runtime is 16

TakiEddine gravatar imageTakiEddine ( 2019-10-30 13:48:16 -0500 )edit

16 == CV_8UC3

your assumption, it would be CV_16U is as wrong as the types in your for loops (please do not write code like that)

berak gravatar imageberak ( 2019-10-30 14:02:36 -0500 )edit

So, although my images are grayscale, the VideoCapture is reading them as if they were in color space, is there anyway to configure the VideoCapture class to read them without change ?

TakiEddine gravatar imageTakiEddine ( 2019-10-31 04:26:47 -0500 )edit

I converted the read frames from color to grayscale and this solved the problem. However, I would like to know whether I can read the images directly as 16-bit grayscale using videoCapture, otherwise, I'm satisfied with the answers provided so far.

TakiEddine gravatar imageTakiEddine ( 2019-10-31 05:11:29 -0500 )edit

Taking a look at the VideoCapture class - i would say its surprisingly not possible. I would have expected the same flags like on imread() but i didn't found anything so far. But its fine - just make an additional convert step - its not too much code(1 line) :-)

holger gravatar imageholger ( 2019-10-31 20:03:28 -0500 )edit

The fact is that I'm using OpenCV only to facilitate the reading and writing operations, I'm really concerned with performance issues here. So an extra conversion step will have its cost. It's really frustrating how the VideoCapture class cannot read grayscale images.

TakiEddine gravatar imageTakiEddine ( 2019-11-02 05:57:05 -0500 )edit

you should probably write a loop and use imread() instead, not VideoCapture

berak gravatar imageberak ( 2019-11-02 06:03:10 -0500 )edit

I'm really concerned with performance issues here.


make it work, then make it fast. in exactly that order.

(and again, NEVER write per-pixel loops, then)

berak gravatar imageberak ( 2019-11-02 06:04:11 -0500 )edit

Alright, I'm not really familiar with strings in c++, so can you tell me how can I format the path to my images, in order to read them in the correct order using imread function ?

TakiEddine gravatar imageTakiEddine ( 2019-11-02 13:14:31 -0500 )edit

1 answer

Sort by ยป oldest newest most voted

answered 2019-11-04 09:28:05 -0500

TakiEddine gravatar image

Using imread function with the flag IMREAD_UNCHANGED in the same manner solved the problem, I can now read the images sequentially without needing to color space step convert.

edit flag offensive delete link more

Question Tools

1 follower


Asked: 2019-10-30 13:25:39 -0500

Seen: 854 times

Last updated: Nov 04 '19