【Emgu CV教程】2.7、基本方法之图像按位运算

程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算就是直接对整数在内存中的二进制位进行操作。比如下面的代码:

int a = 8;
int b = 9;
int c = a + b;

在计算机中,转换成二进制的计算结果就是: 

8    -->    1 0 0 0
9    -->    1 0 0 1

  1 0 0 0
  1 0 0 1
__________
1 0 0 0 1

使用Emgu CV对图像处理时,有时候也需要对图像按位操作。一共四个函数:

  • BitwiseAnd(),按位与,当且仅当两个像素都大于零时,按位与为真,相与取较大值为结果。
  • BitwiseOr(),按位或,如果两个像素中的任何一个大于零,则按位或为真,相或取较小值为结果。
  • BitwiseNot(),按位取反,倒置图像中的“开”和“关”像素。
  • BitwiseXor(),按位异或,两个像素转化为二进制进行异或计算。

先举例子,我们这里有六角形、矩形两张照片,分别作为srcMat1和srcMat2进行演示。

1、BitwiseAnd(),按位与

计算过程如下:

  1. 对图像中的每一像素(矩阵中的每一元素),将数值转换为二进制;
  2. 对 src1 和 src2 同一位置像素的数值进行按位操作 (按位与): 1 and 1=1, 1 and 0=0, 0  and 0=0;
  3. 将位操作的二进制结果转换为十进制。

代码是:

Mat dstMat = new Mat();
CvInvoke.BitwiseAnd(srcMat1, srcMat2, dstMat);
CvInvoke.Imshow("BitwiseAnd image, " + dstMat.Size.ToString(), dstMat);

六角形、矩形两张照片做BitwiseAnd()按位与效果如下:

为什么出现这种形状,因为 六角形.jpg和矩形.jpg的中间部分,都是白色的,P(Blue、Green、Red)的值是P(255、255、255),所以最终图像就是取两幅图每个点的最大值,简单吧。如果用矩形.jpg和街景.jpg做BitwiseAnd()时,是什么样??

结果是这样的: 

为什么两幅图中间白色部分和彩色部分, BitwiseAnd后是彩色呢。如果白色点P1(Blue、Green、Red)的值是P(255、255、255),彩色点P2(Blue、Green、Red)的值是P(120、45、152)。255转成二进制是11111111,120转成二进制是01111000,两个数做按位与,列式子

1 1 1 1 1 1 1 1

0 1 1 1 1 0 0 0
————————————————————
0 1 1 1 1 0 0 0

看到了吧,结果是01111000,转成二进制还是120,同理255和45做BitwiseAnd还是45,255和152做BitwiseAnd还是152。所以:

  • 黑色点与彩色点做BitwiseAnd()按位与,结果是黑色点。
  • 黑色点与黑色点做BitwiseAnd()按位与,结果是黑色点。
  • 黑色点与白色点做BitwiseAnd()按位与,结果是黑色点。
  • 白色点与彩色点做BitwiseAnd()按位与,结果是彩色点。
  • 白色点与黑色点做BitwiseAnd()按位与,结果是黑色点。
  • 白色点与白色点做BitwiseAnd()按位与,结果是白色点。
  • 彩色点与彩色点做BBitwiseAnd()按位与,结果是彩色点,具体自己可以计算一下。

2、BitwiseOr(),按位或

计算过程如下:

  1. 对图像中的每一像素(矩阵中的每一元素),将数值转换为二进制;
  2. 对 src1 和 src2 同一位置像素的数值进行按位操作 (按位或): 1 or 1=1,1 or 0=1,0 or 0=0,0 or 1=1
  3. 将位操作的二进制结果转换为十进制。

代码是:

Mat dstMat = new Mat();
CvInvoke.BitwiseOr(srcMat1, srcMat2, dstMat);
CvInvoke.Imshow("BitwiseOr image, " + dstMat.Size.ToString(), dstMat);

六角形、矩形两张照片做BitwiseOr()按位或效果如下所示: 

结果就是两张图片全部都是白色的部分,但是如果用矩形.jpg和街景.jpg做BitwiseOr()时,效果就是下面这样了:

为什么是这样???如果白色点P1(Blue、Green、Red)的值是P(255、255、255),彩色点P2(Blue、Green、Red)的值是P(120、45、152)。255转成二进制是11111111,120转成二进制是01111000,两个数做按位或,列式子

1 1 1 1 1 1 1 1

0 1 1 1 1 0 0 0
————————————————————
1 1 1 1 1 1 1 1

结果就是1 1 1 1 1 1 1 1,转成十进制就是255,明白了吧。

如果黑色点P1(Blue、Green、Red)的值是P(0、0、0),彩色点P2(Blue、Green、Red)的值是P(120、45、152)。0转成二进制是00000000,120转成二进制是01111000,两个数做按位或,列式子

0 0 0 0 0 0 0 0

0 1 1 1 1 0 0 0
————————————————————
0 1 1 1 1 0 0 0

结果还是 01111000,转换成十进制就是120。所以:

  • 黑色点与彩色点做BitwiseOr()按位或,结果是彩色点。
  • 黑色点与黑色点做BitwiseOr()按位或,结果是黑色点。
  • 黑色点与白色点做BitwiseOr()按位或,结果是白色点。
  • 白色点与彩色点做BitwiseOr()按位或,结果是白色点。
  • 白色点与黑色点做BitwiseOr()按位或,结果是白色点。
  • 白色点与白色点做BitwiseOr()按位或,结果是白色点。
  • 彩色点与彩色点做BitwiseOr()按位或,结果是彩色点,具体自己可以计算一下。

3、BitwiseNot(),按位取反

BitwiseNot()是对二进制数据进行“非”操作,即对图像每个像素值进行二进制“非”操作,~1=0,~0=1,

  1. 对图像中的每一像素(矩阵中的每一元素),将数值转换为二进制;
  2. 对 src1 像素的数值进行按位取反操作: ~1 = 0,~0  = 1
  3. 将位操作的二进制结果转换为十进制。

代码如下:

Mat dstMat = new Mat();
CvInvoke.BitwiseNot(srcMat1, dstMat);
CvInvoke.Imshow("BitwiseNot image, " + dstMat.Size.ToString(), dstMat);

六角形照片做BitwiseNot()按位取反效果如下: 

黑色点P(0、0、0),取反后是P(255、255、255),白色点P(255、255、255)取反后是P(0、0、0)。那么彩色图像呢,以街景.jpg为例,取反后是下图这样:

假如一个彩色点P2(Blue、Green、Red)的值是P(120、45、152),120转换成二进制是01111000,取反后是10000111,转换成十进制就是135。45转换成二进制是00101101,取反后是11010010,转换成十进制就是210。152转换成二进制是10011000,取反后是01100111,转换成十进制就是103,最终结果就是P(135、152、103)。

最简单的理解,BitwiseNot()的P(结果值)=255-P(原始值)。所以:

  • 黑色点做BitwiseNot按位取反,结果是白色点。
  • 白色点做BitwiseNot按位取反,结果是黑色点。
  • 彩色点做BitwiseNot()按位取反,结果是彩色点,具体自己可以计算一下。

4、BitwiseXor(),按位异或

异或运算的数学公式是:

  • 0⊕0=0
  • 0⊕1=1
  • 1⊕0=1
  • 1⊕1=0

代码如下:

Mat dstMat = new Mat();
CvInvoke.BitwiseXor(srcMat1, srcMat2, dstMat);
CvInvoke.Imshow("BitwiseNot image, " + dstMat.Size.ToString(), dstMat);

六角形、矩形两张照片做BitwiseXor()按位异或效果如下: 

白色重叠部分经过异或运算,变成黑色。 而矩形.jpg和街景.jpg做按位异或,结果如下:

举例说明,120转换成二进制是01111000,0转换成二进制是00000000,两个异或结果是01111000,转换成十进制还是120。255转换成二进制是11111111,与120转换后的01111000,0做按位异或,结果10000111,转换成十进制是135。总结: 

  • 黑色点与彩色点做BitwiseXor()按位异或,结果是彩点。
  • 黑色点与黑色点做BitwiseXor()按位异或,结果是黑色点。
  • 黑色点与白色点做BitwiseXor()按位异或,结果是白色点。
  • 白色点与彩色点做BitwiseXor()按位异或,结果是彩色点。
  • 白色点与黑色点做BitwiseXor()按位异或,结果是白色点。
  • 白色点与白色点做BitwiseXor()按位异或,结果是黑色点。
  • 彩色点与彩色点做BitwiseXor()按位异或,结果是彩色点,具体自己可以计算一下。

下一篇讲什么还没想好... ...

原创不易,请勿抄袭。共同进步,相互学习。

  • 33
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值