一、图像加法
(一) cv2.add()
import cv2
import numpy as np
x = np.uint8([250])
y = np.uint8([14])
print(cv2.add(x,y)) ## 相加,opencv超过255的截取为255 250+14 = 264 => 255
## Out[1]: array([[255]], dtype=uint8)
print(x+y) ## 相加,np超过255的会取模运算 (uint8只能表示0-255,所以取模) 250+14 = 264 % 256 = 8
## Out[2]: array([8], dtype=uint8)
add(src1, src2, dst=None, mask=None, dtype=None)
参数说明:
- src1, src2:需要相加的两副大小和通道数相等的图像或一副图像和一个标量。
- 两幅图像相加:相加的两个图片,应该有相同的大小和通道。处理时将两副图像相同位置的像素的灰度值(灰度图像)或彩色像素各通道值(彩色图像)分别相加。
- 一副图像和一个标量(标量即单一的数值)相加:将图像所有像素的各通道值分别与标量进行相加。
- dst:可选参数,输出结果保存的变量。
- mask:图像掩膜,可选参数,为8位单通道的灰度图像,用于指定要更改的输出图像数组的元素,即输出图像像素只有mask对应位置元素不为0的部分才输出,否则该位置像素的所有通道分量都设置为0(黑色)。
- dtype:可选参数,输出图像数组的深度,即图像单个像素值的位数(如RGB用三个字节表示,则为24位,2^3*3)。
import cv2
img1 = cv2.imread("ty.jpg")
x,y = img1.shape[0:2]
img2 = cv2.imread("sugar.jpg")
## 查看两幅图大小和通道数是否一致,若不一致,则使用resize修改
print(img1.shape)
##Out[1]: (854, 740, 3)
print(img2.shape)
##Out[2]: (543, 500, 3)
img3 = cv2.resize(img2,(y,x))
print(img3.shape)
##Out[3]: (854, 740, 3)
## 将两幅图相加
img = cv2.add(img1,img3)
cv2.imshow('ty', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
(二)cv2.addWeighted()
addWeighted()函数是将两张相同大小,相同类型的图片(叠加)线性融合的函数,实现图像混合加权
dst = src1 * alpha + src2 * beta + gamma;。
cv2.addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype=-1)
- src1:需要加权的第一个数组
- alpha:第一个数组的权重
- src2:第二数组(与第一个数组需要拥有同一个尺寸和通道数)
- beta:第二个数组的权重值,值为1-alpha
- gamma:一个加到权重总和上的标量值,可以理解为加权和后的图像的偏移量
- dst:输出的数组
- dtype:可选,输出阵列的深度,有默认值-1。
import cv2
def add_W(img1_path,img2_path,alpha=0.6,beta=0.4,gamma=0):
img_1 = cv2.imread(img1_path)
x,y = img_ty.shape[0:2]
img_2 = cv2.imread(img2_path)
img_3 = cv2.resize(img_2,(y,x))
img_aw = cv2.addWeighted(img_1,alpha,img_3,beta,gamma)
cv2.imshow('ty', img_aw)
cv2.waitKey(0)
cv2.destroyAllWindows()
add_W("ty.jpg","sugar.jpg",0.8,0.2)
(三) 滑动条
- cv2.createTrackbar(“滑动条的名字”, “滑动条被放置的窗口的名字”, 滑动条的默认值, 滑动条的最大值, 回调函数):绑定滑动条和窗口,定义滚动条的数值。
- cv2.getTrackbarPos(“滑动条名字”,“所在窗口”):返回滑动条的数值。
- cv2.setTrackbarPos(“滑动条名字”,“所在窗口”, 滑动条默认值)
注:滑动条返回的值为整数。
import cv2
import numpy as np
## 创建窗口
cv2.namedWindow("ty")
## 图片读取,保持两张图片数组大小一致
img_ty = cv2.imread("ty.jpg")
x,y = img_ty.shape[0:2]
img_candy = cv2.imread("sugar.jpg")
img_candy = cv2.resize(img_candy,(y,x))
## 用来存放两张图片加权后的结果
img = np.zeros((x,y,3),np.uint8)
alpha = 0.5
## 定义回滚函数
def callback(x):
global img_ty,img_candy,img,alpha
alpha = cv2.getTrackbarPos("alpha","ty")
alpha = alpha * 0.01
beta = 1-alpha
img = cv2.addWeighted(img_ty,alpha,img_candy,beta,0)
cv2.createTrackbar("alpha","ty",0,100,callback)
cv2.setTrackbarPos("alpha", "ty", 80)
while(True):
if cv2.waitKey(1) == ord('q'): ## waitKey的值不能为0
break
cv2.imshow("ty",img)
cv2.destroyAllWindows()
二、图像位运算
(一)二值化
阈值分割其实就是图像分离,对于阈值内的你想如何操作,一个最简单的例子就是二值图像。
1.cv2.threshold()
threshold:固定阈值二值化。
ret, dst = cv2.threshold(src, thresh, maxval, type)
参数解释:
- src:输入图,只能输入单通道图像,通常来说为灰度图
- thresh:阈值
- maxval:阈值最大值,当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值
- type:二值化操作的类型
- ret:方法是否执行成功
- dst:目标图像
type | 类型 | 解释 |
---|---|---|
cv2.THRESH_BINARY | 二进制阈值化 | 大于阈值 的像素点的灰度值设定为最大值255,小于的设定为0。if(像素点>阈值,maxval,0) |
cv2.THRESH_BINARY_INV | 反二进制阈值化 | if(像素点>阈值,0,maxval) |
cv2.THRESH_TRUNC | 截断阈值化 | if(像素点>阈值,阈值,像素点) |
cv2.THRESH_TOZERO | 阈值化为0 | if(像素点>阈值,像素点,0) |
cv2.THRESH_TOZERO_INV | 反阈值化为0 | if(像素点>阈值,0,像素点) |
2.cv.adaptiveThreshold()
adaptiveThreshold:自适应阈值二值化。自适应阈值二值化函数根据图片一小块区域的值来计算对应区域的阈值,从而得到也许更为合适的图片。
dst = cv2.adaptiveThreshold(src, maxval, adaptiveMethod, type, Block Size, C)
参数解释:
- src:输入图,只能输入单通道图像,通常来说为灰度图
- maxval:阈值最大值,当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值
- adaptiveMethod: 自适应方法,平均或高斯
- type:二值化操作的类型
- Block Size: 图片中分块的大小,值要为奇数
- C :偏移值调整量,计算adaptiveMethod用到的参数
adaptiveMethod | 类型 | 解释 |
---|---|---|
ADAPTIVE_THRESH_MEAN_C | 平均 | 所有像素周围的权值相同 |
ADAPTIVE_THRESH_GAUSSIAN_C | 高斯 | (x,y)周围的像素的权值则根据其到中心点的距离通过高斯方程得到 |
(二)位与运算
当且仅当两个像素都大于零时,按位AND才为真。将数字转换成二进制形式–>对同一位上的数字进行and运算(1&1=1,1&0=0,0&0=0)–>将and操作后的二进制转换回十进制并输出。
255的二进制码为11111111,任何数字与之与运算都为他本身。
0的二进制码为00000000,任何数字与之与运算都为0。
bitwise_and(src1, src2, dst=None, mask=None)
参数解释:
- src1、src2:为输入图像或标量,标量可以为单个数值或一个四元组。
- dst:可选输出变量,如果需要使用非None则要先定义,且其大小与输入变量相同。
- mask:图像掩膜,可选参数,为8位单通道的灰度图像,输出图像像素只有mask对应位置元素不为0的部分才输出,否则该位置像素的所有通道分量都设置为0。
1.默认情况
mask默认为区域不为0,即不为黑色。
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('ty.jpg')
ImgMask = np.zeros(img.shape,dtype=np.uint8)
ImgMask[10:200,300:450] = 255
img_mask = cv2.bitwise_and(img,ImgMask) ## 默认不为0的区域输出
cv2.imshow('ty', img_mask)
cv2.waitKey(0)
cv2.destroyAllWindows()
2.mask参数
定义mask为黄色。
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('ty_yell.jpg')
## 使用hsv模型提取想要的颜色,下提取黄色
img_hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
lower_yell = np.array([20,43,43])
upper_yell = np.array([38,255,255])
mask = cv2.inRange(img_hsv,lower_yell,upper_yell)
res = cv2.bitwise_and(img,img,mask=mask)
cv2.imshow('ty_ori', img)
cv2.imshow('ty_ext', res)
cv2.waitKey(0)
cv2.destroyAllWindows()
(三)位或运算
如果两个像素中的任何一个大于零,则按位“或”为真。将数字转换成二进制形式–>对同一位上的数字进行or运算(1|1=1,1|0=1,0|0=0)–>将and操作后的二进制转换回十进制并输出。
bitwise_or(src1, src2, dst=None, mask=None)
import cv2
import numpy as np
img_ty = cv2.imread('ty_black.jpg')
x,y = img_ty.shape[0:2]
img = cv2.resize(img_ty, (int(y / 2), int(x / 2)))
ImgMask = np.zeros(img.shape,dtype=np.uint8)
ImgMask[ImgMask == 0] = 255
ImgMask[5:300,80:280] = 0
img_mask = cv2.bitwise_or(img,ImgMask)
cv2.imshow('img', img)
cv2.imshow('mask', ImgMask)
cv2.imshow('ty_mask', img_mask)
cv2.waitKey(0)
cv2.destroyAllWindows()
(四)位异或运算
当且仅当两个像素一个大于0一个小于0时才为真。将数字转换成二进制形式–>对同一位上的数字进行^运算(1 ^ 1=0,1 ^ 0=1,0 ^ 0=0)–>将and操作后的二进制转换回十进制并输出。
bitwise_xor(src1, src2, dst=None, mask=None)
1.画长方形
cv2.rectangle(image, start_point, end_point, color, thickness)
参数解释:
- image:要在其上绘制矩形的图像。
- start_point:矩形的起始坐标。(X,Y)
- end_point:矩形的结束坐标。(X,Y)
- color:绘制的矩形边界线颜色。(B,G,R)
- thickness:矩形边框线的粗细像素。厚度-1像素将以指定的颜色填充矩形形状。
2.画圆形
cv2.circle(image, center_coordinates, radius, color, thickness)
参数解释:
- image:要在其上绘制圆形的图像。
- center_coordinates:圆的中心坐标。(X,Y)
- radius:圆的半径。
- color:绘制的圆边界线颜色。(B,G,R)
- thickness:圆边界线的粗细像素。厚度-1像素将以指定的颜色填充矩形形状。
import cv2
import numpy as np
## 创建两个300*300图像
rect = np.zeros((300,300),dtype = np.uint8)
circle = np.zeros((300,300),dtype = np.uint8)
## 在rect图像中填充一个长方形,在circle图像中填充一个圆形
cv2.rectangle(rect,(25,25),(275,275),255,-1)
cv2.circle(circle,(150,150),150,255,-1)
## 对两个图像进行位异或运算
res = cv2.bitwise_xor(rect,circle)
cv2.imshow('rect', rect)
cv2.imshow('circle', circle)
cv2.imshow('res', res)
cv2.waitKey(0)
cv2.destroyAllWindows()
(五)位非运算
倒置图像中的“开”和“关”像素。~(A) = -(A+1)
bitwise_not(src, dst=None, mask=None)
import cv2
import numpy as np
## 创建一个300*300图像
rect = np.zeros((300,300),dtype = np.uint8)
## 在rect图像中填充一个长方形
cv2.rectangle(rect,(25,25),(275,275),255,-1)
## 对两个图像进行位异或运算
res = cv2.bitwise_not(rect)
cv2.imshow('rect', rect)
cv2.imshow('res', res)
cv2.waitKey(0)
cv2.destroyAllWindows()