1
votes

I want to do three-channel image filtering with the help of the C++ OpenCV library. I want to do it with kernels of 3x3 matrix size, each of which is of different value. To do this, I first divided the RGB image into three channels: red, green and blue. Then I defined different kernel matrices for these three channels. Then, after processing them with the help of the filter2d function, the code threw an exception:

Unhandled exception at 0x00007FFAA150A388 in opencvTry.exe: Microsoft C++ exception: cv::Exception at memory location 0x0000002D4CAF9660. occurred

What is the reason I can't do it in the code below?

#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <typeinfo>
#include <stdlib.h>

using namespace cv;
using namespace std;

int main()
{
Mat src = imread("path\\color_palette.png", IMREAD_COLOR); //load  image


int blue_array[159][318];
int green_array[159][318];
int red_array[159][318];
for (int i = 0; i < src.rows; i++) {
    for (int j = 0; j < src.cols; j++) {
        int a = int(src.at<Vec3b>(i, j).val[0]);
        blue_array[i][j] = a;
        //cout << blue_array[i][j] << ' ' ;
        int b = int(src.at<Vec3b>(i, j).val[1]);
        green_array[i][j] = b;
        int c = int(src.at<Vec3b>(i, j).val[2]);
        red_array[i][j] = c;
    }
}



cv::Mat blue_array_mat(159, 318, CV_32S, blue_array);
cv::Mat green_array_mat(159, 318, CV_32S, green_array);
cv::Mat red_array_mat(159, 318, CV_32S, red_array);



float kernelForBlueData[9]  = { 1,0,1, 2,0,-2, 1,0,-1};
cv::Mat kernelForBlue(3, 3, CV_32F, kernelForBlueData);
float  kernelForGreenData[9] = { 1./16, 2./16, 1./16, 2./16, 4./16,2./16, 1./16, 2./16, 1./16 };
cv::Mat kernelForGreen(3, 3, CV_32F,  kernelForGreenData);
float  kernelForRedData[9]  = { 1./9,1./9, 1./9, 1./9, 1./9,1./9, 1./9, 1./9,1./9 };
cv::Mat kernelForRed(3, 3, CV_32F,  kernelForRedData);



//cv::filter2D(blue_array_mat, blue_array_mat, -1, kernelForBlue, Point(-1, -1), 5.0, BORDER_REPLICATE);
filter2D(blue_array_mat, blue_array_mat, 0, kernelForBlue);

imshow("filter", blue_array_mat);



waitKey(0);
return 0;
}
1

1 Answers

0
votes

You’re using a constructor for cv::Mat that expects a pointer to data (e.g. int*) but you put an int** into it. This is the reason for the crash, I presume.

Why not create the cv::Mat first and then directly write data into it?

Note the OpenCV has a function that does this for you:

cv::Mat chans[3];
cv::split(src, chans);
//...
cv::filter2D(chans[2], chans[2], 0, kernelForBlue);