# OpenCV Mat的位操作

# bitwise_or

Mat中的数据按位取或,也就是取不为0的部分。

对于单通道,直接比较两个Mat对应位置的元素。
对于多通道,分别比较每个通道上对应位置的元素,取非零值。

函数原型:

CV_EXPORTS_W void bitwise_or(InputArray src1, 
                             InputArray src2,
                             OutputArray dst, 
                             InputArray mask = noArray());
  • src1\src2输入矩阵
  • dst输出矩阵
  • mask``0/1组成的掩码矩阵,只作用在mask==1的位置

使用实例:

#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>

int main()
{
    cv::Mat src1 = cv::Mat::zeros(cv::Size(5, 5), CV_8UC3);
    cv::Mat src2 = cv::Mat::zeros(cv::Size(5, 5), CV_8UC3);
    src1.setTo(cv::Scalar(255, 0, 0));
    src2.setTo(cv::Scalar(0, 255, 0));
    std::cout << src1 << std::endl;
    std::cout << src2 << std::endl;
    cv::imshow("src1", src1);
    cv::imshow("src2", src2);
    cv::Mat dst;
    cv::bitwise_or(src1, src2, dst);
    std::cout << dst << std::endl;
    cv::imshow("dst", dst);
    cv::waitKey(0);
}

编译上面的程序:

g++ main.cpp -o main `pkg-config --libs --cflags opencv4`

执行程序输出如下:

src1: [255,   0,   0, 255,   0,   0;
 255,   0,   0, 255,   0,   0]
src2: [  0, 255,   0,   0, 255,   0;
   0, 255,   0,   0, 255,   0]
dst: [255, 255,   0, 255, 255,   0;
 255, 255,   0, 255, 255,   0]

可以看到,对于三通道矩阵的或,分别对每个通道上的值进行了或。255,0,00,255,0或的结果是255,255,0

# bitwise_and

Mat中的数据按位取与,也就是都不为0的部分。

对于单通道,直接取两个Mat对应位置元素的按位与的结果。
对于多通道,分别取每个通道上对应位置元素按位与的结果。

函数原型:

CV_EXPORTS_W void bitwise_and(InputArray src1, 
                              InputArray src2,
                              OutputArray dst, 
                              InputArray mask = noArray());
  • src1\src2输入矩阵
  • dst输出矩阵
  • mask``0/1组成的掩码矩阵,只作用在mask==1的位置

实例:

#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>

int main()
{
    cv::Mat src1 = cv::Mat::zeros(cv::Size(2, 2), CV_8UC3);
    cv::Mat src2 = cv::Mat::zeros(cv::Size(2, 2), CV_8UC3);
    src1.setTo(cv::Scalar(255, 0, 255));
    src2.setTo(cv::Scalar(0, 255, 125));
    std::cout << src1 << std::endl;
    std::cout << src2 << std::endl;
    cv::imshow("src1", src1);
    cv::imshow("src2", src2);
    cv::Mat dst;
    cv::bitwise_and(src1, src2, dst);
    std::cout << dst << std::endl;
    cv::imshow("dst", dst);
    cv::waitKey(0);
}

参考上面编译,执行输出:

src1: [255,   0, 255, 255,   0, 255;
       255,   0, 255, 255,   0, 255]
src2: [  0, 255, 125,   0, 255, 125;
         0, 255, 125,   0, 255, 125]
dst: [  0,   0, 125,   0,   0, 125;
        0,   0, 125,   0,   0, 125]

可以看到255,0,2550,255,125按位与的结果是0,0,125

bitwise_andMat &的区别:

int main()
{
    cv::Mat mat = (cv::Mat_<int>(2,2) << 2,0,0,2);
    cv::Mat mask = (cv::Mat_<int>(2,2) << 2,2,2,2);
    cv::Mat result;
    std::cout << "before &1:\n" << mat << std::endl;
    result = mat & 1;
    std::cout << "after &1:\n" << result << std::endl;
    // before &1:
    // [2, 0;
    // 0, 2]
    // after &1:
    // [0, 0;
    // 0, 0]
    std::cout << "before &2:\n" << mat << std::endl;
    result = mat & 2;
    std::cout << "after &2:\n" << result << std::endl;
    // before &2:
    // [2, 0;
    // 0, 2]
    // after &2:
    // [2, 0;
    // 0, 2]
}

# bitwise_xor

Mat中的数据按位取异或,也就是取不同的部分。

1001^1010 = 0011

对于单通道,直接取两个Mat对应位置元素的按位异或的结果。
对于多通道,分别取每个通道上对应位置元素按位异或的结果。

函数原型:

CV_EXPORTS_W void bitwise_xor(InputArray src1, 
                              InputArray src2,
                              OutputArray dst, 
                              InputArray mask = noArray());

实例:

#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>

int main()
{
    cv::Mat src1 = cv::Mat::zeros(cv::Size(2, 2), CV_8UC3);
    cv::Mat src2 = cv::Mat::zeros(cv::Size(2, 2), CV_8UC3);
    src1.setTo(cv::Scalar(255, 0, 255));
    src2.setTo(cv::Scalar(0, 255, 125));
    std::cout << src1 << std::endl;
    std::cout << src2 << std::endl;
    cv::imshow("src1", src1);
    cv::imshow("src2", src2);
    cv::Mat dst;
    cv::bitwise_xor(src1, src2, dst);
    std::cout << dst << std::endl;
    cv::imshow("dst", dst);
    cv::waitKey(0);
}

编译执行,输出:

src1: [255,   0, 255, 255,   0, 255;
       255,   0, 255, 255,   0, 255]
src2: [  0, 255, 125,   0, 255, 125;
         0, 255, 125,   0, 255, 125]
dst: [255, 255, 130, 255, 255, 130;
      255, 255, 130, 255, 255, 130]

关于最后为什么是130是因为,255的二进制11111111,而125的二进制01111101,按位异或后为10000010转为十进制为130

# bitwise_not

Mat中的数据按位取反。

~1001 = 0110

对于单通道,直接取Mat对应位置元素的按位取反的结果。
对于多通道,分别取每个通道上对应位置元素按位取反的结果。

函数原型:

CV_EXPORTS_W void bitwise_not(InputArray src, OutputArray dst,
                              InputArray mask = noArray());

  • src输入矩阵
  • dst输出矩阵
  • mask``0/1组成的掩码矩阵,只作用在mask==1的位置

实例:

#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>

int main()
{
    cv::Mat src2 = cv::Mat::zeros(cv::Size(2, 2), CV_8UC3);
    src2.setTo(cv::Scalar(0, 255, 125));
    std::cout << src2 << std::endl;
    cv::imshow("src2", src2);
    cv::Mat dst;
    cv::bitwise_not(src2, dst);
    std::cout << dst << std::endl;
    cv::imshow("dst", dst);
    cv::waitKey(0);
}

程序运行结果:

# src: [  0, 255, 125,   0, 255, 125;
#     0, 255, 125,   0, 255, 125]
# dst: [255,   0, 130, 255,   0, 130;
#       255,   0, 130, 255,   0, 130]

uchar8 bit的数据0二进制表示为00000000按位取反就是11111111,转为十进制就是255

十进制数125对应的二进制数为01111101,按位异或后为10000010转为十进制为130

所以可以得到如上结果。

(adsbygoogle = window.adsbygoogle || []).push({});

# reference

1.https://docs.opencv.org/4.8.0/d2/de8/group__core__array.html#ga0002cf8b418479f4cb49a75442baee2f (opens new window)