【OpenCV-Python】教程:2-2 图像算术运算

目标

  • 学会图像间算术运算,
  • 图像相加
  • 图像相减
  • 图像按位运算等等
  • cv2.add(), cv2.addWeighted(), 等等

【图像相加】

OpenCV 是饱和运算(大于255算255),NumPy 是模运算(大于255会与256进行求模)。

import numpy as np
import cv2

x = np.uint8([250])
y = np.uint8([10])
print( cv2.add(x,y) ) # 250+10 = 260 => 255
print( x+y )          # 250+10 = 260 % 256 = 4
import numpy as np
import cv2

im0 = cv2.imread('opencv-logo.png')
h0, w0, c0 = im0.shape
resizeratio = 0.5

im = cv2.resize(im0, [int(w0 * resizeratio), int(h0 * resizeratio)])
h, w, c = im0.shape

# 创建图像大小、深度与读入图像相同的图像
h, w, c = im.shape
img_create255 = np.zeros((h, w, c), np.uint8)
img_create255 = img_create255 + 255

imadd255_numpy = im + 255
imadd255_cv = cv2.add(im, img_create255)

cv2.imshow("im", im)
cv2.imshow("imadd255_numpy", imadd255_numpy)
cv2.imshow("imadd255_cv", imadd255_cv)
cv2.imshow("create", img_create255)
cv2.waitKey(0)
cv2.destroyAllWindows()

【OpenCV-Python】教程:2-2 图像算术运算_第1张图片

从图中可以看出,源图像与白色图像用 NumPy 的方式相机,会进行模运算;而用 cv2.add 进行相加,会进行向上饱和运算(大于 255时设置值为 255)。

【图像混合】

带权重的图像相加 cv2.addWeighted ,

公式如下

d s t = α ⋅ i m g 1 + β ⋅ i m g 2 + γ dst = α·img1 + β·img2 + γ dst=αimg1+βimg2+γ

import numpy as np
import cv2

img1 = cv2.imread('ml.png')
img2 = cv2.imread('opencv-logo-white.png')
dst = cv2.addWeighted(img1, 0.7, img2, 0.3, 0)


cv2.imshow('ml', img1)
cv2.imshow('logo', img2)
cv2.imshow('dst', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

【OpenCV-Python】教程:2-2 图像算术运算_第2张图片

【按位运算】

需要将图2放到图1中,形成图3的效果;

图1
【OpenCV-Python】教程:2-2 图像算术运算_第3张图片

图2
【OpenCV-Python】教程:2-2 图像算术运算_第4张图片

图3 效果图

【OpenCV-Python】教程:2-2 图像算术运算_第5张图片

如果直接 cv2.addWeighted(img2, 0.7, roi, 0.3, 0) 的效果如下:

【OpenCV-Python】教程:2-2 图像算术运算_第6张图片

CODE

import numpy as np
import cv2

# 加载图像
img1 = cv2.imread('messi5.jpg')
img2 = cv2.imread('opencv-logo-white2.png')

# 创建一个ROI,将opencv logo 放到 messi5图像里
# 注意,这里两幅图像的大小千万不要越界,也就是 img2 的大小不要超过 img1 的大小
rows, cols, channels = img2.shape
roi = img1[0:rows, 0:cols]

# logo的mask图像并取反;灰度化,阈值化,取反
img2gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)

# 阈值化
ret, mask = cv2.threshold(img2gray, 10, 255, cv2.THRESH_BINARY)

# 取反
mask_inv = cv2.bitwise_not(mask)

# ROI 非图标部分保留原图,
img1_bg = cv2.bitwise_and(roi, roi, mask = mask_inv)

# 保留 logo 的图标部分
img2_fg = cv2.bitwise_and(img2, img2, mask=mask)

# 两部分的图像相加
dst = cv2.add(img1_bg, img2_fg)
img1[0:rows, 0:cols] = dst

cv2.imshow('res', img1)
cv2.waitKey(0)
cv2.destroyAllWindows()

接口

函数原型

// 计算像素级别的绝对差值
void cv::absdiff	(	InputArray 	src1,
InputArray 	src2,
OutputArray 	dst 
);	


// 计算两个图像相加得到的结果
void cv::add	(	InputArray 	src1,
InputArray 	src2,
OutputArray 	dst,
InputArray 	mask = noArray(),
int 	dtype = -1 
);

// 带权重的两个数组或图像相加
void cv::addWeighted	(	InputArray 	src1,
double 	alpha,
InputArray 	src2,
double 	beta,
double 	gamma,
OutputArray 	dst,
int 	dtype = -1 
);

// 按位与
void cv::bitwise_and	(	InputArray 	src1,
InputArray 	src2,
OutputArray 	dst,
InputArray 	mask = noArray() 
);

// 按位取反
void cv::bitwise_not	(	InputArray 	src,
OutputArray 	dst,
InputArray 	mask = noArray() 
);

// 按位或
void cv::bitwise_or	(	InputArray 	src1,
InputArray 	src2,
OutputArray 	dst,
InputArray 	mask = noArray() 
);

// 按位异或
void cv::bitwise_xor	(	InputArray 	src1,
InputArray 	src2,
OutputArray 	dst,
InputArray 	mask = noArray() 
);
cv2.absdiff(	src1, src2[, dst]	) ->	dst

cv2.add(	src1, src2[, dst[, mask[, dtype]]]	) ->	dst

cv2.addWeighted(	src1, alpha, src2, beta, gamma[, dst[, dtype]]	) ->	dst

cv2.bitwise_and(	src1, src2[, dst[, mask]]	) ->	dst

cv2.bitwise_not(	src[, dst[, mask]]	) ->	dst

cv2.bitwise_or(	src1, src2[, dst[, mask]]	) ->	dst

cv2.bitwise_xor(	src1, src2[, dst[, mask]]	) ->	dst

参数

  • src1: 第一个输入
  • src2: 第二个输入
  • dst: 输出,尺寸和类型与输入一致
  • mask: 可选参数, 8位单通道图像,可以作用于输出
  • dtype: 可选参数,深度
  • alpha: 第一个输入的权重
  • beta: 第二个输入的权重
  • gamma: 添加到和上的标量

更多参考

【参考】

  1. Arithmetic Operations on Images

你可能感兴趣的:(#,OpenCV,#,Python,opencv,python)