@[TOC]
图像的算术运算
1.饱和加 cv2.add()
OpenCV中的add()
函数是饱和运算,也就是说,如果两个8位整数相加,超过了255,自动会截断成255.
1 2 3 4 5 6 7 8
| >>> x = np.uint8([250]) >>> y = np.uint8([10])
>>> print cv2.add(x,y) # 250+10 = 260 => 255 [[255]]
>>> print x+y # 250+10 = 260 % 256 = 4 [4]
|
2. 图像混合 cv2.addWeighted()
图像混合的数学表达式如下,原理就是将两张图片按照一定的比例(透明度)进行融合,产生的图片也一般会存在一种“透明”的感觉。
在OpenCV中参数的表达与上式略有不同,有以下三个参数α、β,γ
。
1 2 3 4 5 6 7 8
| img1 = cv2.imread('ml.png') img2 = cv2.imread('opencv_logo.jpg')
dst = cv2.addWeighted(img1,0.7,img2,0.3,0)
cv2.imshow('dst',dst) cv2.waitKey(0) cv2.destroyAllWindows()
|
结果如下:
这里,我做了一个类似幻灯片淡入淡出效果的gif动图,由一张图动态过度到另一张,==一定记得把颜色通道翻转一下!!!== 代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| def slide_view(): img1 = cv2.resize(cv2.imread('bear.jpg'), (500, 500)) img2 = cv2.imread('OpenCV-logo.jpg')
fps = 20 buff = [] for i in range(fps): alpha = i / fps beta = 1 - i / fps dst = cv2.addWeighted(img1, alpha, img2, beta, 0)
cv2.imshow('dst', dst) buff.append(dst[:, :, ::-1])
cv2.waitKey(int(1000 / fps)) cv2.destroyAllWindows() gif = imageio.mimsave('logo2bear.gif', buff, 'GIF', duration=0.1)
|
这里效果图是gif不太好上传,你可以自己运行一下上述代码。
3. 图像位操作
上述融合中有一个问题,就是会产生“透明”的效果,有时候我们又不想这样,而是直接把一个图片A放在图片B的上面,这时候位操作就发挥了作用,大致将一下思路(这里记待插入的前景图片为A,插入到的那个图片为B):
- 先取出图片B的ROI。
- 先将图片A灰度化(如果已经是灰度图当然就无需这步),记为grayA。
- 将grayA二值化(取一个阈值,比如说10),小于10的像素为0,其他为1,记二值化后的图片为mask,为了后续需要,将mask按位取反得到mask_inv。
- 利用
cv2.bitwise_and(roi, roi, mask=mask_inv)
将图片B的ROI区域变黑。注意:bitwise_and的运算机制如下:
- 利用
cv2.bitwise_and(imgA, imgA, mask=mask)
将图片A的前景取出。
- 把前景加到背景变黑的区域。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| def bitwise_ops(): # cv2.namedWindow('123', cv2.WINDOW_NORMAL)
img = cv2.imread("man.jpg") img_logo = cv2.imread("OpenCV-logo.jpg")
# ROI rows, cols, channels = img_logo.shape roi = img[0:rows, 0:cols]
# 新建一个logo的mask图片 img_logo_gray = cv2.cvtColor(img_logo, cv2.COLOR_BGR2GRAY) cv2.imshow("123", img_logo_gray) cv2.waitKey(0) ret, mask = cv2.threshold(img_logo_gray, 10, 255, cv2.THRESH_BINARY) cv2.imshow("123", mask) cv2.waitKey(0) mask_inv = cv2.bitwise_not(mask) cv2.imshow("123", mask_inv) cv2.waitKey(0)
# 先把背景的ROI区域变黑 img_bg = cv2.bitwise_and(roi, roi, mask=mask_inv) cv2.imshow("123", img_bg) cv2.waitKey(0)
# 取出logo的前景 img_lg = cv2.bitwise_and(img_logo, img_logo, mask=mask) cv2.imshow("123", img_lg) cv2.waitKey(0)
# 把logo前景放到变黑的背景图区域 dst = cv2.add(img_bg, img_lg) img[0:rows, 0:cols] = dst
cv2.imshow('123', img) cv2.waitKey(0) cv2.destroyAllWindows()
|
效果如下: