使用 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;
}
}
}
总结一下我的问题如下:
- 如何为 Mat 类型的 temp 分配内存?
- 如何访问帧的各个像素以便应用模板?
- mp4类型是三通道RGB吗?或一个通道,如果是这样,这就是我的模板不适用于像素的原因吗?我需要包括 rgb.y 和 rgb.z 吗?如果是这样,我如何知道我的 mp4 视频文件是否具有三个通道以及如何访问它们?
我之前曾与 CImg 合作过,他们基本上将数据排列在三维 3 x 宽 x 高数组中,我可以在其中访问像素,但我如何使用 openCV 做到这一点?
在OpenCV中,可以使用Mat constructor指定Mat的大小(高、宽、通道),内存会被分配。您正在使用默认构造函数,它不会初始化对象。
访问像素值的方法有多种。您可以使用 Mat .at() 方法,您可以访问原始数据指针...除了 Mat 参考(检查 link),您还可以找到更多信息 here or here.
默认情况下,我认为 VideoCapture 会将帧转换为 BGR 色彩空间,因此您将拥有 3 个通道(蓝色、绿色、红色)。您还可以直接从 Mat 对象检查通道数和其他信息(检查文档 link)。
我正在尝试编写一个 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;
}
}
}
总结一下我的问题如下:
- 如何为 Mat 类型的 temp 分配内存?
- 如何访问帧的各个像素以便应用模板?
- mp4类型是三通道RGB吗?或一个通道,如果是这样,这就是我的模板不适用于像素的原因吗?我需要包括 rgb.y 和 rgb.z 吗?如果是这样,我如何知道我的 mp4 视频文件是否具有三个通道以及如何访问它们? 我之前曾与 CImg 合作过,他们基本上将数据排列在三维 3 x 宽 x 高数组中,我可以在其中访问像素,但我如何使用 openCV 做到这一点?
在OpenCV中,可以使用Mat constructor指定Mat的大小(高、宽、通道),内存会被分配。您正在使用默认构造函数,它不会初始化对象。
访问像素值的方法有多种。您可以使用 Mat .at() 方法,您可以访问原始数据指针...除了 Mat 参考(检查 link),您还可以找到更多信息 here or here.
默认情况下,我认为 VideoCapture 会将帧转换为 BGR 色彩空间,因此您将拥有 3 个通道(蓝色、绿色、红色)。您还可以直接从 Mat 对象检查通道数和其他信息(检查文档 link)。