如何在 cv::Mat 上应用 bitwise_and?

Posted

技术标签:

【中文标题】如何在 cv::Mat 上应用 bitwise_and?【英文标题】:how to apply bitwise_and on cv::Mat? 【发布时间】:2017-01-04 03:10:54 【问题描述】:

我正在尝试在 OpenCV 的帮助下将卡通滤镜应用于 UIImage。我的代码如下

+ (UIImage *)createCartoonizedImageFromImage:(UIImage *)inputImage 

int num_down = 2; //number of downsampling steps

cv::Mat image_rgb = [self cvMatFromUIImage:inputImage];

cv::Mat image_color;
cv::cvtColor(image_rgb, image_color, cv::COLOR_RGBA2RGB);

//downsample image using Gaussian pyramid
for(int i = 0; i < num_down; i++)

    cv::pyrDown(image_color, image_color);


// apply bilateral filter
cv::Mat image_bilateral = image_color.clone();
cv::bilateralFilter(image_color, image_bilateral, 9, 9, 7);

// upsample image to original size
for(int i = 0; i < num_down; i++)

    cv::pyrUp(image_color, image_color);


// convert to grayscale
cv::Mat image_gray;
cv::cvtColor(image_rgb, image_gray, cv::COLOR_RGB2GRAY);

// apply median blur
cv::Mat image_blur;
cv::medianBlur(image_gray, image_blur, 7);

// detect and enhance edges
cv::Mat image_edge;
cv::adaptiveThreshold(image_blur, image_edge, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, 9, 2);

// convert back to color, bit-AND with color image
cv::cvtColor(image_edge, image_edge, cv::COLOR_GRAY2RGB);
cv::Mat image_cartoon;
cv::bitwise_and(image_bilateral, image_edge, image_cartoon);

UIImage *cartoonImage = [self UIImageFromCVMat:image_cartoon];
return cartoonImage;


上线

cv::bitwise_and(image_bilateral, image_edge, image_cartoon);

上面的代码给了我以下错误

OpenCV Error: Sizes of input arguments do not match (The operation is neither 'array op array' (where arrays have the same size and type), nor 'array op scalar', nor 'scalar op array') in binary_op, file /Users/kyle/code/opensource/opencv/modules/core/src/arithm.cpp, line 225
libc++abi.dylib: terminating with uncaught exception of type cv::Exception: /Users/kyle/code/opensource/opencv/modules/core/src/arithm.cpp:225: error: (-209) The operation is neither 'array op array' (where arrays have the same size and type), nor 'array op scalar', nor 'scalar op array' in function binary_op

我的问题

我知道问题在于输入数组的大小不正确。但是我怎样才能纠正它们并使它们具有相同的大小而不影响最终结果呢?

【问题讨论】:

【参考方案1】:

正如 OpenCV 错误中明确指出的:“输入参数的大小不匹配”。即 image_bilateral.size != image_edge.size()。一个简单的调试打印就可以了!所以下次尝试使用你的调试器!这是您修改后的代码!

    int num_down = 2; //number of downsampling steps

    cv::Mat image_rgb = imread(FileName1,1);

    cv::Mat image_color;
    cv::cvtColor(image_rgb, image_color, cv::COLOR_RGBA2RGB);

    //downsample image using Gaussian pyramid
    for(int i = 0; i < num_down; i++)
    
        cv::pyrDown(image_color, image_color);
    

    // apply bilateral filter
    cv::Mat image_bilateral = image_color.clone();
    cv::bilateralFilter(image_color, image_bilateral, 9, 9, 7);

    // upsample image to original size
    for(int i = 0; i < num_down; i++)
    
        cv::pyrUp(image_color, image_color);
        cv::pyrUp(image_bilateral, image_bilateral);//Bug <-- Here Missing to Resize the bilateralFilter image?
    

    // convert to grayscale
    cv::Mat image_gray;
    //cv::cvtColor(image_rgb, image_gray, cv::COLOR_RGB2GRAY);//Bug <-- Using RGBA instead of RGB
    cv::cvtColor(image_color, image_gray, cv::COLOR_RGB2GRAY);

    // apply median blur
    cv::Mat image_blur;
    cv::medianBlur(image_gray, image_blur, 7);

    // detect and enhance edges
    cv::Mat image_edge;
    cv::adaptiveThreshold(image_blur, image_edge, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, 9, 2);

    // convert back to color, bit-AND with color image
    cv::cvtColor(image_edge, image_edge, cv::COLOR_GRAY2RGB);
    cv::Mat image_cartoon;

    //cv::bitwise_and(image_bilateral, image_edge, image_cartoon);//Bug <-- Here Size of image_bilateral is 1/4 of the image_edge
    cv::bitwise_and(image_bilateral, image_edge, image_cartoon);

    imshow("Cartoon ",image_cartoon);

【讨论】:

以上是关于如何在 cv::Mat 上应用 bitwise_and?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 cv::Mat 类型从 CV_16UC1 转换为 CV_8UC1

如何在向量中找到相同的 cv::Mat<cv::Mat>

如何正确将 cv::Mat 转换为 CV_8UC1?

如何正确地将 cv::Mat 转换为具有完美匹配值的 torch::Tensor?

如何将 cv::Mat 设为 2 x 2 最大值均值?

cv::Mat 转换为特征矩阵并返回