目标是使用三个不同的模板对图像rgb三个通道分别进行滤波,但是opencv的filter2d函数原理是src图像的三个通道共用一个kernel,办法是将图像三个通道分别提取出来,分别进行滤波,最后再拼接成dst。
#include结果 暑期编程PK赛 得CSDN机械键盘等精美礼品!#include #include using namespace cv; void cv_filter_test(String str) { Mat img = imread(str); Mat img_b(img.size(), CV_8UC1); Mat img_g(img.size(), CV_8UC1); Mat img_r(img.size(), CV_8UC1); for (int i = 0; i < img.rows; i++) { unsigned char* p_src = img.ptr (i); unsigned char* p_b = img_b.ptr (i); unsigned char* p_g = img_g.ptr (i); unsigned char* p_r = img_r.ptr (i); for (int j = 0; j < img.cols; j++) { *(p_b + j) = *(p_src + j * 3); *(p_g + j) = *(p_src + j * 3 + 1); *(p_r + j) = *(p_src + j * 3 + 2); } p_src += img.step; p_b += img_b.step; p_g += img_g.step; p_r += img_r.step; } Mat kern_b = (Mat_ (5, 5) << 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 2, 4, 2, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0) / 16; Mat kern_g = (Mat_ (5, 5) << 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, -2, 0, 2, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0); Mat kern_r = (Mat_ (5, 5) << 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) / 25; Mat dst_b, dst_g, dst_r; filter2D(img_b, dst_b, img.depth(), kern_b, Point(-1, -1), 0.0, BORDER_DEFAULT); filter2D(img_g, dst_g, img.depth(), kern_g, Point(-1, -1), 0.0, BORDER_DEFAULT); filter2D(img_r, dst_r, img.depth(), kern_r, Point(-1, -1), 0.0, BORDER_DEFAULT); Mat dst(img.size(), img.type()); for (int i = 0; i < dst.rows; i++) { unsigned char* p_dst = dst.ptr (i); unsigned char* p_b = dst_b.ptr (i); unsigned char* p_g = dst_g.ptr (i); unsigned char* p_r = dst_r.ptr (i); for (int j = 0; j < dst.cols; j++) { *(p_dst + j * 3) = *(p_b + j); *(p_dst + j * 3 + 1) = *(p_g + j); *(p_dst + j * 3 + 2) = *(p_r + j); } p_dst += dst.step; p_b += dst_b.step; p_g += dst_g.step; p_r += dst_r.step; } imshow("dst", dst); waitKey(0); } int main() { String str = "lena.jpg"; cv_filter_test(str); return 0; }



