目录
1 阀值操作
1.1 简单阀值
1.2 OTSU二值化
1.3 自适应阀值
2 图像上的运算
2.1 加减法
2.2 图像混合
2.3 按位运算
1 阀值操作
1.1 简单阀值
像素值高于阈值时,我们给这个像素赋予一个新值(可能是白色),否则我们给它赋予另外一种颜色(也许是黑色)。这个函数就是cv2.threshold(src, thresh, maxval, type[, dst]) 第一个参数就是原图像,原图像应该是灰度图。第二个参数就是用来对像素值进行分类的阈值。第三个参数就是当像素值高于(有时是小于)阈值时应该被赋予的新的像素值。OpenCV提供了多种不同的阈值方法,这是有第四个参数来决定的。
cv2.THRESH_BINARY|| cv2.THRESH_BINARY_INV || cv2.THRESH_TRUNC || cv2.THRESH_TOZERO|| cv2.THRESH_TOZERO_INV
""" Python阀值操作 """
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('5.jpg')
img_Gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
""" 将大于127小于等于255的值设为255,其余设为0 """
ret,thresh1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
""" 将大于127小于等于255的值设为0,其余设为255 """
ret,thresh2 = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV)
""" 将大于127小于等于255的值设为255,其余设为不变"""
ret,thresh3 = cv2.threshold(img,127,255,cv2.THRESH_TRUNC)
""" 将大于127小于等于255的值不变,其余设为0 """
ret,thresh4 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO)
""" 将大于127小于等于255的值设为0,其余不变 """
ret,thresh5 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO_INV)
titles = ['Original Image','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']
images = [img_Gray, thresh1, thresh2, thresh3, thresh4, thresh5]
for i in range(6):
plt.subplot(2,3,i+1)
plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
1.2 OTSU二值化
由OTSU算子寻找全局最佳的阀值。
import cv2
img = cv2.imread("..\Image\SpongeBobSquarePants.jpg") """ 读取图片 """
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) """ 将图片转为灰度图 """
ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) """ 将初始阀值设为0,由算法去寻找全局最佳的阀值 """
cv2.imshow("gray",gray)
cv2.imshow('binary', binary)
cv2.waitKey(0)
1.3 自适应阀值
前面的部分我们使用是全局阈值,整幅图像采用同一个数作为阈值。当时这种方法并不适应与所有情况,尤其是当同一幅图像上的不同部分的具有不同亮度时。这种情况下我们需要采用自适应阈值。此时的阈值是根据图像上的每一个小区域计算与其对应的阈值。因此在同一幅图像上的不同区域采用的是不同的阈值,从而使我们能在亮度不同的情况下得到更好的结果。这种方法需要我们指定三个参数,返回值只有一个。
- Adaptive Method- 指定计算阈值的方法。
cv2.ADPTIVE_THRESH_MEAN_C:阈值取自相邻区域的平均值
cv2.ADPTIVE_THRESH_GAUSSIAN_C:阈值取值相邻区域的加权和,权重为一个高斯窗口。
- Block Size - 邻域大小(用来计算阈值的区域大小)。
- C - 这就是是一个常数,阈值就等于的平均值或者加权平均值减去这个常数
""" Python自适应阀值 """
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('4.jpg', 0)
img = cv2.GaussianBlur(img, (5, 5), 0)
ret, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
th2 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)
th3 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
titles = ['Original Image', 'Global Thresholding (v = 127)', 'Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding']
images = [img, th1, th2, th3]
for i in range(4):
plt.subplot(2, 2, i + 1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()
2 图像上的运算
2.1 加减法
""" Python """
import cv2
import numpy as np
x = np.uint8([245]) """ 非uint8数据类型只是普通加法 """
y = np.uint8([255])
print(cv2.add(x, y)) """ x + y 打印结果:[[255]] """
print(cv2.subtract(x,y)) """ x - y 打印结果:[[0]] """
2.2 图像混合
这其实也是加法,但是不同的是两幅图像的权重不同,这就会给人一种混合或者透明的感觉。图像混合 的计算公式如下: g(x)=(1−\alpha) f_{0} (x) + \alpha f_{1} (x)
通过修改 α 的值(0 → 1),可以实现非常多的混合。 现在我们把两幅图混合在一起。第一幅图的权重是 0.7,第二幅图的权重是 0.3。函数 cv2.addWeighted() 可以按下面的公式对图片进行混合操作。 dst = α · img1 + β · img2 + γ 这里 γ 的取值为 0。
""" Python """
import cv2
""" 两张图片大小需要一样:同w、同h、同通道数 """
dog_img = cv2.imread("../Image/dog.jpg")
dog_img = cv2.resize(dog_img,(960,540))
bg_img = cv2.imread("../Image/bg.jpg")
bg_img = cv2.resize(bg_img,(960,540))
print(dog_img.shape, bg_img.shape) """ 打印结果:(540, 960, 3) (540, 960, 3) """
cv2.imshow("dog ", dog_img)
cv2.imshow("bg ", bg_img)
_img = cv2.addWeighted(dog_img, 0.7, bg_img, 0.2,gamma=0)
cv2.imshow("_img", _img)
cv2.waitKey(0)
cv2.destroyAllWindows()
下图红字为截图时添加。
2.3 按位运算
这里包括的按位操作有:AND,OR,NOT,XOR 等。当我们提取图像的一部分,选择非矩形 ROI 时这些操作会很有用
import cv2
img1 = cv2.imread('1.jpg')
img2 = cv2.imread('9.jpg')
rows, cols, channels = img2.shape
roi = img1[0:rows, 0:cols]
img2gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
ret, mask = cv2.threshold(img2gray, 10, 255, cv2.THRESH_BINARY)
mask_inv = cv2.bitwise_not(mask)
# cv2.imshow("mask_inv",mask_inv)
""" 按照mask进行镂空操作 """
img1_bg = cv2.bitwise_and(roi, roi, mask=mask_inv)
# cv2.imshow("img1_bg",img1_bg)
img2_fg = cv2.bitwise_and(img2, img2, mask=mask)
# cv2.imshow("img2_fg",img2_fg)
dst = cv2.add(img1_bg, img2_fg)
img1[0:rows, 0:cols] = dst
cv2.imshow('res', img1)
cv2.waitKey(0)
作者:阳一子