python——opencv:图像简单处理

1.灰度变换:
灰度图像中,R=G=B,常用方法是R=G=B=(R前+G前+B前)/3,即等于灰度变换前RGB的平均值(opencv中的imread方法是以BGR的格式读入图像的,但opencv的imshow无需进行反转)。

import cv2 as cv

image = cv.imread("source_one.jpg")

# 将RGB图像转为灰度图
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)

# cv.imshow("Image", image)
cv.imshow("Gray Image", gray)
cv.waitKey(0)
cv.destroyAllWindows()

在这里插入图片描述
在这里插入图片描述

2.二值变换:
使得灰度图像中的灰度值为0(黑)或者255(白),图像整体呈现黑白颜色。若灰度值为0,那么R=G=B=0;若灰度值为255,那么R=G=B=255。这里就需要设定一个阈值,使得小于该阈值的像素位置处的灰度值为0,大于该阈值的灰度值为255。

(1)自定义阈值:n个像素点灰度值的平均值。

image = cv.imread("source_one.jpg")

# 将RGB图像转为灰度图
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)

h, w = gray.shape

# 手动计算二值化阈值
threshold = gray.sum() / (h * w)

# 将高于阈值的灰度值赋值255,低于阈值的赋值为0
ret, binary = cv.threshold(gray, threshold, 255, cv.THRESH_BINARY)

cv.imshow("Binary Image", binary)
cv.waitKey(0)
cv.destroyAllWindows()

在这里插入图片描述
(2)OTSU大律法,全局自适应阈值,又称最大类间方差法,最大化前景像素和背景像素之间的方差,使得前景和背景被分错的概率最小

ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_OTSU)

0可以取任何值,无作用。

(3)triangle三角形法求阈值:
三角形法求阈值

ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_TRIANGLE)

在这里插入图片描述
(4)二值化反转,即小于阈值的灰度值为255,大于阈值的灰度值为0。

image = cv.imread("source_one.jpg")

# 将RGB图像转为灰度图
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)

h, w = gray.shape

# 手动计算二值化阈值
threshold = gray.sum() / (h * w)

ret, binary = cv.threshold(gray, threshold, 255, cv.THRESH_BINARY_INV)

在这里插入图片描述
其余二值化方法可以参照这篇博客图像的二值化之python+opencv
3.图像反色,即RGB分别按位取反,即255减去当前像素值。

img_rev = cv.bitwise_not(image)

在这里插入图片描述
4.绘制灰度直方图:

import cv2 as cv
import matplotlib.pyplot as plt

image = cv.imread("source_one.jpg")

# 将RGB图像转为灰度图
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
m, n = gray.shape

gray_hist = {}
for k in range(256):
    gray_hist.setdefault(k, 0)
for i in range(m):
    for j in range(n):
        gray_hist[gray[i, j]] += 1

gray_order = list(gray_hist.keys())
gray_num = list(gray_hist.values())
plt.bar(range(256), gray_num, color='c')
plt.title("Gray histogram")
plt.show()

在这里插入图片描述
5.形态学腐蚀、膨胀
简单来说,就是用一个模板对图像进行扫描,模板的大小决定了腐蚀和膨胀的程度。在腐蚀操作中,用模板的中心点扫描图像中的每一个像素点,并且模板覆盖区域的像素值与模板中心点扫描的图像上的像素点做与运算,只要模板覆盖区域有一个像素位置处的像素值为0,则该点像素值就为0,当模板覆盖区域所有像素位置处的像素值为1时,该点处的像素值才为1,在二值化图像中,白色区域会被腐蚀掉,由于黑色区域的像素值为0,0与任何值做与运算结果都是0,所以此时黑色占主导因素,会腐蚀掉白色区域,只有模板覆盖的区域完全被白色区域包含时,白色区域才能保留下来。在膨胀操作中,是做或运算,在二值化图像中,白色区域膨胀,由于白色区域的像素值为1,在或运算中有一个位置处的像素值为1,则结果为1,此时白色区域占主导因素,白色区域膨胀而黑色区域相对来说就被白色区域腐蚀掉了。

另外,这篇博客对腐蚀和膨胀讲的也非常详细图像的腐蚀(erode)和膨胀(dilate) 开运算以及闭运算------理论知识及其对应函数
采用3*3模板的腐蚀与膨胀:

kernel = np.ones((3, 3), np.uint8)
# 形态学腐蚀
erosion = cv.erode(binary, kernel)

cv.imshow("Erosion Image", erosion)
cv.waitKey(0)
cv.destroyAllWindows()

在这里插入图片描述

kernel = np.ones((3, 3), np.uint8)
dilation = cv.dilate(binary, kernel)

#形态学膨胀
cv.imshow("Dilation Image", dilation)
cv.waitKey(0)
cv.destroyAllWindows()

在这里插入图片描述
6.形态学开操作、闭操作:
这篇博客讲解的比较详细
形态学应用——图像开运算与闭运算

import cv2 as cv
import numpy as np

image = cv.imread("card.jpg")

# 将RGB图像转为灰度图
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)

# 大律法选择阈值
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_OTSU)
kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
morph_close = cv.morphologyEx(binary, cv.MORPH_CLOSE, kernel)
morph_open = cv.morphologyEx(binary, cv.MORPH_OPEN, kernel)

morph_image = np.hstack((morph_open, morph_close))
cv.imshow("morph_open morph_close", morph_image)
cv.waitKey(0)
cv.destroyAllWindows()

在这里插入图片描述
左图为开运算,右图为闭运算。
7.图像掩膜:
掩膜可以理解为自定义一个模板,通过该模板扫描图像以获取ROI区域:

import cv2 as cv
import numpy as np

image = cv.imread("card.jpg")

mask = np.zeros([517, 690], dtype=np.uint8)
mask[180:410, 48:658] = 255  # ROI区域填充为白色
image_mask = cv.add(image, np.zeros(np.shape(image), np.uint8), mask=mask)

cv.imshow("Original&Mask", image_mask)
cv.waitKey(0)
cv.destroyAllWindows()

在这里插入图片描述
在这里插入图片描述
也可以通过像素之间的与运算来获取ROI区域:

image_mask = cv.bitwise_and(image, image, mask=mask)

除此之外,还可以通过设置颜色的上下限来创建模板以提取ROI区域:

import cv2 as cv
import numpy as np

image = cv.imread("card.jpg")

lower = np.array([90, 80, 150])
upper = np.array([225, 225, 225])
mask = cv.inRange(image, lower, upper)
image_mask = cv.bitwise_and(image, image, mask=mask)

cv.imshow("Mask", image_mask)
cv.waitKey(0)
cv.destroyAllWindows()

在这里插入图片描述
(这里设置的颜色上下限是基于BGR通道,而不是RGB,因为imread是以BGR的格式读取图像。)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章