使用 OpenCV C++ 访问帧数据

Accessing frame data with OpenCV C++

我正在尝试编写一个 Gaussian Blurr OpenCv 程序,我在其中输入一个 mp4 视频,逐帧读取它,然后对每一帧应用一个 3x3 模板,该模板基本上使图像模糊。但是,我的问题是我不知道如何访问每一帧的数据。我试过 "frame.data" 这样做:

int main(int argc, const char** argv) {

// VideoCapture class for playing video for which faces to be detected 
VideoCapture capture;
Mat frame,temp, image;

// PreDefined trained XML classifiers with facial features 
CascadeClassifier cascade, nestedCascade;
double scale = 1;

// Load classifiers from "opencv/data/haarcascades" directory  
nestedCascade.load("C:/opencv/sources/data/haarcascades/haarcascade_eye_tree_eyeglasses.xml");

// Change path before execution  
cascade.load("C:/opencv/sources/data/haarcascades/haarcascade_frontalcatface.xml");

// Start Video..1) 0 for WebCam 2) "Path to Video" for a Local Video 
capture.open("C:/Users/antho/Downloads/videoplayback.mp4");


capture >> frame;
Mat frame1 = frame.clone();
int width = capture.get(CV_CAP_PROP_FRAME_WIDTH);
int height = capture.get(CV_CAP_PROP_FRAME_HEIGHT);
size_t frame_size = 360 * 640 * sizeof(unsigned char);

cout << "Width: " << width << endl;;
cout << "Height: " << height;
unsigned char* d_src;
unsigned char* d_gs;
d_gs = new unsigned char[frame_size];

serialTest(frame1.data, temp.data, width, height);

imshow("blurr", temp);
waitKey(0);

我知道我必须先为临时分配数据,但我也不知道该怎么做。我在 d_dst[j * width + i]:

抛出异常错误
void serialTest(const unsigned char d_src[], unsigned char d_dst[], int width, int height) {

for (int j = 1; j < width - 1; j++) {
     for(int i = 1; i <height -1; i++){

        uchar3 rgb; // (i)(j)
        rgb.x = d_src[j * width + i];

        uchar3 rgb1; //(i-1)(j-1)
        rgb1.x = d_src[(j - 1) * width + (i - 1)];

        uchar3 rgb2; //(i)(j-1)
        rgb2.x = d_src[(j - 1) * width + i];

        uchar3 rgb3; //(i+1)(j-1)
        rgb3.x = d_src[(j - 1) * width + (i + 1)];

        uchar3 rgb4; //(i-1)(j)
        rgb4.x = d_src[(j)*width + (i - 1)];

        uchar3 rgb5; //(i+1)(j)
        rgb5.x = d_src[j * width + (i + 1)];

        uchar3 rgb6; //(i-1)(j+1)
        rgb6.x = d_src[(j + 1) * width + (i - 1)];

        uchar3 rgb7; //(i)(j+1)
        rgb7.x = d_src[(j + 1) * width + i];

        uchar3 rgb8; //(i+1)(j+1)
        rgb8.x = d_src[(j + 1) * width + (i + 1)];

        unsigned char blurr_rgbx = (unsigned char)(rgb.x * (0.25f) + (rgb5.x + rgb4.x + rgb7.x + rgb2.x) * (0.125f) + (rgb1.x + rgb3.x + rgb6.x + rgb8.x) * (0.0625f));

        d_dst[j * width + i] = blurr_rgbx;
    }
}

}

总结一下我的问题如下:

  1. 如何为 Mat 类型的 temp 分配内存?
  2. 如何访问帧的各个像素以便应用模板?
  3. mp4类型是三通道RGB吗?或一个通道,如果是这样,这就是我的模板不适用于像素的原因吗?我需要包括 rgb.y 和 rgb.z 吗?如果是这样,我如何知道我的 mp4 视频文件是否具有三个通道以及如何访问它们? 我之前曾与 CImg 合作过,他们基本上将数据排列在三维 3 x 宽 x 高数组中,我可以在其中访问像素,但我如何使用 openCV 做到这一点?
  1. 在OpenCV中,可以使用Mat constructor指定Mat的大小(高、宽、通道),内存会被分配。您正在使用默认构造函数,它不会初始化对象。

  2. 访问像素值的方法有多种。您可以使用 Mat .at() 方法,您可以访问原始数据指针...除了 Mat 参考(检查 link),您还可以找到更多信息 here or here.

  3. 默认情况下,我认为 VideoCapture 会将帧转换为 BGR 色彩空间,因此您将拥有 3 个通道(蓝色、绿色、红色)。您还可以直接从 Mat 对象检查通道数和其他信息(检查文档 link)。