预备知识:
图像ROI:
图像ROI(Region Of Interest),即感兴趣的区域,该操作能够非常轻松的通过numpy的切片操作实现。
注意切片操作后对ROI像素值的更改也会影响到原图,如果不想影响到原图,先将roi做一个copy操作就好,roi_copy = roi.copy()
图像像素值的界限
两个uint8的ndarray相加,值超过255的部分将会以对256取模的方式返回到结果中,在减法中由于无符号减法是两数的补码相减,减完后再返回相应的原码(不想细说这部分了。。几乎没有人会用到无符号整数的越界操作),所以给人一种首尾相连的感觉。
比如:254+10=8,10-20=246
而用opencv的add与subtract对两个uint8 ndarray操作的化会自动clip到[0, 255]上,所以在对像素做加减法的时候最好用opencv的函数,结果一定会符合预期!
比如:254+10=255,10-20=0
图像像素的逻辑操作
像素逻辑操作共有四种,三种为二元操作类型:与,或,异或操作,一种为一元操作类型:非

特点:1. 图像最好是是二值图像,即像素点的值要么是0,要么就是255,没有其他值。不是二值图像的话opencv也支持。 2.像素级的操作,也就是对应像素间的操作,所以两图像大小必须一致。

逻辑与:两个都为真才是真,cv2.bitwise_and(img1, img2, mask)
逻辑或:有一个为真就是真,cv2.bitwise_or(img1, img2, mask)
逻辑异或:两者不同为真,cv2.bitwise_xor(img1, img2, mask)
逻辑非:原先为假结果就是真,原先为真结果就是假,cv2.bitwise_not(img1,mask)
掩膜
上面的函数最后一项都为mask,这就是掩膜,具体作用就是真正要进行操作的区域,因为有的时候我们并不需要对整个图像进行操作。
掩膜的大小与原图像相同,为二值图像,我们真正要操作的区域就是掩膜图像中的非零部分(即灰度值为255的部分),与ROI的功能相同吧。
总结:
1、用numpy的切片操作可以很方便的提取图像ROI
2、对图像的加减运算最好用cv2.add()和cv2.subtract()防止出现意想不到的错误
3、四种基于像素点的逻辑操作
4、掩膜图像上为255的地方进行相应的逻辑操作,掩膜图像的大小应与原图保持一致!

import cv2 as cv
 import numpy as npsrc=cv.imread(r’C:\Users\zs\Desktop\defm.jpg’)
 cv.namedWindow(‘input’,cv.WINDOW_AUTOSIZE)
 cv.imshow(‘input’,src)
 h,w=src.shape[:2]cy=h//2
 cx=w//2
 roi=src[cy-100:cy+100,cx-100:cx+100,:]
 cv.imshow(‘roi’,roi)image=np.copy(roi)
roi[:,:,0]=0
 cv.imshow(‘result’,src)image[:,:,2]=0
 cv.imshow(‘result’,src)
 cv.imshow(‘copy roi’,image)src2=cv.imread(r’C:\Users\zs\Desktop\defm.jpg’)
 cv.imshow(‘src2’,src2)
 hsv=cv.cvtColor(src2,cv.COLOR_BGR2HSV)
 mask=cv.inRange(hsv,(35,43,46),(99,255,255))mask=cv.bitwise_not(mask)
 person=cv.bitwise_and(src2,src2,mask=mask)result=np.zeros(src2.shape,src2.dtype)
 result[:,:,0]=255mask=cv.bitwise_not(mask)
 dst=cv.bitwise_or(person,result,mask=mask)
 dst=cv.add(dst,person)cv.imshow(‘dst’,dst)
cv.waitKey(0)
 cv.destroyAllWindows()