-1

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:

  1. How do I allocate memory for the Mat type temp?
  2. How do I access individual pixels of the frames so I can apply the stencil?
  3. 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?
Abhishek Bhagate
  • 5,583
  • 3
  • 15
  • 32
anthonym650
  • 49
  • 1
  • 7
  • Here is an example how to use `Videocapture` in opencv https://docs.opencv.org/master/d8/dfe/classcv_1_1VideoCapture.html – 김선달 Jun 09 '20 at 09:02

1 Answers1

1
  1. In OpenCV, you can use Mat constructor to specify the size (height, width, channels) of the Mat, and the memory will be allocated. You are using the default constructor, which does not initialize the object.

  2. There are different ways to access the pixel values. You could use the Mat .at() method, you can access the raw data pointer... Besides from the Mat reference (check link), you can find more information here or here.

  3. By default, I think VideoCapture converts the frames to the BGR colorspace, so you will have 3 channels (blue, green, red). You can also check the number of channels and other information from the Mat object directly (check documentation link).

Fran
  • 61
  • 3