I'm trying to write a Gaussian Blurr OpenCv program where I input a mp4 video , read it frame by frame, and to each frame I apply a 3x3 stencil that essentially blurrs the image. However, my problem is that I don't know how to access the data of every frame. I tried doing "frame.data" this way:
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);
I do understand that I have to allocate data for temp first but I don't know how to do that as well. I have an exception error thrown at 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;
}
}
}
To summarize my problems are the following:
- How do I allocate memory for the Mat type temp?
- How do I access individual pixels of the frames so I can apply the stencil?
- Are mp4 types three channels RGB? or one single channel, if so, is that why my stencil isn't applying to the pixels? do I need to include rgb.y and rgb.z? if so, how can I know if my mp4 video file has three channels and how do I access them? I've worked with CImg before and they essentially had their data arranged in a three dimensional 3 x width x height array where I was able to access the pixels but how can I do this with openCV?