OpenCV常用函数分析之bitwise_and

cv2.bitwise_and(src1, src2, mask=None)

  • src1 :参与运算的第一幅图(决定输出图像的颜色)。
  • src2 :参与运算的第二幅图(决定输出图像的尺寸位深 ,通常与 src1 相同)。
  • mask :可选参数。如果是单通道图像(黑白),只有值为 255 (白色) 的像素才会进行运算,值为 0 (黑色) 的像素结果强制为 0 (黑色)
2. 为什么要传两个 img

因为按位与运算(Bitwise AND)是两个图像之间 的运算:
Result ( x , y ) = src1 ( x , y ) & src2 ( x , y ) \text{Result}(x,y) = \text{src1}(x,y) \ \& \ \text{src2}(x,y) Result(x,y)=src1(x,y) & src2(x,y)

  • 如果 src1src2 都是原图 img
    • 数学上: A & A = A A \ \& \ A = A A & A=A (任何数和自己做"与"运算,结果还是它自己)。
    • 实际效果 :颜色完全保留原图,唯一改变图像的是 mask
3. 如果没有 mask 会怎样?

如果不传 mask,代码变成:

python 复制代码
red_object = cv2.bitwise_and(img, img)
  • 结果:red_object 会和 img 一模一样 (因为 A & A = A A \ \& \ A = A A & A=A)。
  • 毫无意义
4. 加上 mask 后发生了什么?
python 复制代码
red_object = cv2.bitwise_and(img, img, mask=mask)

OpenCV 内部逻辑如下:

  • 遍历每一个像素点 ( x , y ) (x, y) (x,y)
    • 如果 mask[x, y] == 255 (白色):
      • 计算 img[x, y] & img[x, y] → 结果保留原图颜色。
    • 如果 mask[x, y] == 0 (黑色):
      • 结果直接设为 0 (黑色),不执行上面的与运算。

🎨 视觉效果演示

假设原图是一个红苹果,mask 是一个圆形的白色区域(苹果形状),背景是黑色。

步骤 图像内容 作用
src1 🍎 红苹果 提供"红色"这个颜色数据
src2 🍎 红苹果 提供"苹果形状"这个尺寸数据
mask ⚪ 白圆圈 + ⚫ 黑背景 关键! 告诉程序:只保留圆圈里的东西
结果 🍎 红苹果 + ⚫ 黑背景 圆圈外变成了纯黑,圆圈内保留了红色

❓ 常见疑问

Q: 第二个 img 可以换成别的吗?
A: 可以,但必须满足两个条件:

  1. 尺寸必须完全一致(高、宽一样)。
  2. 通道数必须兼容(通常也是一样的 BGR 三通道)。

如果你传一张全白的图作为第二个参数:

python 复制代码
white_img = np.ones_like(img) * 255
result = cv2.bitwise_and(img, white_img, mask=mask)
  • 逻辑:原图颜色 & 白色 (255)
  • 数学: A & 255 = A A \ \& \ 255 = A A & 255=A。
  • 结果:和传两个 img 是一模一样的

结论 :传两个 img 只是最方便、最直观的写法,表示"我想保留原图的颜色,但在 mask 指定的区域显示"。


✅ 总结代码意图

python 复制代码
# 这句话的直译:
# "请给我原图 (img),但是在 mask 为黑色的地方把它涂黑,只留下 mask 为白色的部分。"
red_object = cv2.bitwise_and(img, img, mask=mask)

这就是提取红色物体(或任何掩膜区域)的标准写法!

🔦 超级通俗理解:手电筒照画

想象你在一个漆黑的房间里:

  1. 第一个 img = 墙上挂的一幅画(这是你要看的东西)。
  2. 第二个 img = 另一幅一模一样的画 (这是为了配合运算规则,暂时先不管它,你就当它是备用的画)。
  3. mask = 一个手电筒
    • 手电筒照到的地方(白色区域)=
    • 没照到的地方(黑色区域)=
🎬 现在的操作是:

你拿着手电筒(mask),对着第一幅画 (第一个 img)照。

  • 被照亮的地方:你看到了画原本的颜色(保留了原图)。
  • 没照到的地方:一片漆黑(变成了黑色背景)。
❓ 那为什么要拿第二幅画 (第二个 img)出来?

这是因为电脑(OpenCV)是个死脑筋的会计,它的规矩是:

"要做'与'运算(bitwise_and),我必须手里拿着两张纸进行对比,少一张我都不干活!"

  • 既然你的目的是**"保留第一张画的原样",那你只能再拿一张 一模一样**的画(第二个 img)递给它。
  • 电脑拿着两张一模一样的画一比对:
    • "嗯,这张是红色,那张也是红色 → 结果还是红色。"
    • "嗯,这张是蓝色,那张也是蓝色 → 结果还是蓝色。"
  • 最后,它再盖上"手电筒"(mask)的章:只有光照到的地方才把比对结果显示出来,没照到的地方直接涂黑。

💡 一句话总结

传两个 img,是因为电脑强制要求必须有两张图才能做运算

  • 因为我们不想改变颜色,所以故意传了两张一模一样的图去"骗"过电脑的规则。
  • 真正起作用的"剪刀",其实是后面的 mask

如果写成人类语言,这行代码的意思是:

"电脑,给你两张一模一样的图(img, img),请你帮我做个比对(结果肯定还是原图),但是! 只用把手电筒(mask)照到的地方显示出来,其他地方给我涂黑!"

相关推荐
H Journey2 小时前
OpenCV之Canny 边缘检测与MediaPipe 人物分割
人工智能·opencv·计算机视觉·mediapipe
Sagittarius_A*3 小时前
霍夫变换:几何特征检测与量化验证【计算机视觉】
图像处理·人工智能·opencv·算法·计算机视觉·霍夫变换
H Journey3 小时前
OpenCV之边缘检测与高斯模糊
opencv·边缘检测·高斯模糊
光羽隹衡3 小时前
计算机视觉——Opencv(模块风格迁移)
人工智能·opencv·计算机视觉
爱打代码的小林3 小时前
OpenCV 实战:绘制花朵的精确轮廓与近似轮廓
人工智能·opencv·计算机视觉
qianbo_insist3 小时前
鱼眼图像的三维投影逆变换和AI计算
人工智能·opencv·算法
纤纡.1 天前
基于 OpenCV 的银行卡号识别:传统计算机视觉实战详解
人工智能·opencv·计算机视觉
啊哈哈哈哈哈啊哈哈1 天前
答题卡检测
人工智能·opencv·计算机视觉
强风7941 天前
OpenCV的创建与配置
人工智能·opencv·计算机视觉