import cv2
import numpy as np
img = cv2.imread("test02.jpg", 1)
# cvtcolor()函数是一个颜色空间转换函数,可以实现RGB颜色向HSV,HSI等颜色空间转换。也可以转换为灰度图。
# img:输入图片; cv2.COLOR_BGR2GRAY:转换方式,还有cv2.COLOR_BGR2Lab等;
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow("src", gray)
dst = cv2.equalizeHist(gray)
cv2.imshow("dst", dst)
cv2.waitKey(0)
原图:
灰度图:
灰度直方图均衡化之后:
彩色直方图均衡化:彩色图像的直方图均衡化和灰度图像略有不同,需要将彩色图像先用split()方法,将三个通道拆分,然后分别进行均衡化.最后使用merge()方法将均衡化之后的三个通道进行合并.操作如下:
import cv2
import numpy as np
img = cv2.imread("test02.jpg", 1)
cv2.imshow("src", img)
# 彩色图像均衡化,需要分解通道 对每一个通道均衡化
(b, g, r) = cv2.split(img)
bH = cv2.equalizeHist(b)
gH = cv2.equalizeHist(g)
rH = cv2.equalizeHist(r)
# 合并每一个通道
result = cv2.merge((bH, gH, rH))
cv2.imshow("dst", result)
cv2.waitKey(0)
import cv2 as cv
import numpy as np
img = cv.imread('niguang_01.jpg', 0)
cv.imshow("yuantu", img)
# 全局直方图均衡化
img1 = cv.equalizeHist(img)
cv.imshow("junhenghua", img1)
# 自适应直方图均衡化
clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
cll = clahe.apply(img)
cv.imshow("CLAHE", cll)
cv.waitKey(0)
原图:
全局直方图均衡化:
限制对比度自适应直方图均衡化:
9.限制对比度自适应直方图均衡(CLAHE)
10.CLAHE的计算步骤
11.空间域处理及其变换–滤波/卷积
12.均值滤波示意
均值滤波本身存在缺陷,既没有很好地去除噪声点,也破坏了图像的细节反而使图像变得模糊。
代码:
给图片加噪音:
# -*- coding:utf-8 -*-
import cv2
import numpy as np
# 读取图片
img = cv2.imread("test02.jpg", 1)
img_noise = img
cv2.imshow("src", img)
rows, cols, chn = img_noise.shape
# 加噪声
for i in range(5000):
x = np.random.randint(0, rows)
y = np.random.randint(0, cols)
img_noise[x, y, :] = 255
cv2.imshow("noise", img_noise)
# 等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()
# 保存含噪声图像
cv2.imwrite("test02_noise.jpg", img_noise)
平滑均值滤波:
# encoding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 读取图片
img = cv2.imread('test02_noise.jpg')
source = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 均值滤波
result = cv2.blur(source, (3, 3)) # 可以更改核的大小
# 显示图形
cv2.imshow('src', source)
cv2.imshow('dst', result)
# 等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()
原图:
加噪音后:
平滑均值滤波后:
13.平滑中值滤波/卷积
代码:
# encoding:utf-8
import cv2
# 读取图片
img = cv2.imread('test02_noise.jpg')
# 中值滤波
# 1)随着核大小逐渐变大,会让图像变得更加模糊;
# 2)核必须是大于1的奇数,如3、5、7等;
# 3)在代码dst = cv2.medianBlur(src, ksize)中填写核大小时,只需填写一个数即可,如3、5、7等.
result = cv2.medianBlur(img, 3) # 可以更改核的大小,必须是奇数
# 显示图像
cv2.imshow("source img", img)
cv2.imshow("medianBlur", result)
# 等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()
噪音图像:
平滑中值滤波后:
14.平滑高斯滤波/卷积
代码:
# encoding:utf-8
import cv2
# 读取图片
img = cv2.imread('test02_noise.jpg')
source = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 高斯滤波
# dst = cv2.GaussianBlur(src, ksize, sigmaX)
# 其中,参数:
# src:表示原始图像;
# ksize:表示核大小;
# sigmaX:表示X方向方差。
# 注:核大小(N, N)必须是奇数,X方向方差主要控制权重。
# 1)随着核大小逐渐变大,会让图像变得更加模糊;
# 2)核大小(N, N)必须是大于1的奇数,如3、5、7等;
result = cv2.GaussianBlur(source, (3, 3), 0) # 可以更改核大小
# 显示图像
cv2.imshow("source img", source)
cv2.imshow("GaussianBlur", result)
# 等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()
平滑高斯滤波后:
15.梯度Prewitt滤波/卷积
代码:
import cv2
from pylab import *
saber = cv2.imread("test03.jpg")
# 首先将原图像进行边界扩展,并将其转换为灰度图。
gray_saber = cv2.cvtColor(saber, cv2.COLOR_RGB2GRAY)
# gray_saber = cv2.resize(gray_saber, (200, 200))
def PreWittOperator(roi, operator_type):
if operator_type == "horizontal":
prewitt_operator = np.array([[-1, -1, -1], [0, 0, 0], [1, 1, 1]])
elif operator_type == "vertical":
prewitt_operator = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]])
else:
raise ("type Error")
result = np.abs(np.sum(roi * prewitt_operator))
return result
def PreWittAlogrithm(image, operator_type):
new_image = np.zeros(image.shape)
# cv2.copyMakeBorder:扩充src的边缘,将图像变大,然后以各种外插方式自动填充图像边界,这个函数实际上
# 调用了函数cv::borderInterpolate,这个函数最重要的功能就是为了处理边界,比如均值滤波或者中值滤波
# 中,使用copyMakeBorder将原图稍微放大,然后我们就可以处理边界的情况了。
# 参数含义:源图像;四个方向上边界的长度;边界的类型
image = cv2.copyMakeBorder(image, 1, 1, 1, 1, cv2.BORDER_DEFAULT)
for i in range(1, image.shape[0] - 1):
for j in range(1, image.shape[1] - 1):
new_image[i - 1, j - 1] = PreWittOperator(image[i - 1:i + 2, j - 1:j + 2], operator_type)
new_image = new_image * (255 / np.max(image))
return new_image.astype(np.uint8)
# 显示图像
cv2.imshow("source img", saber)
cv2.imshow("horizontal", PreWittAlogrithm(gray_saber, "horizontal"))
cv2.imshow("vertical", PreWittAlogrithm(gray_saber, "vertical"))
# 等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()
# plt.subplot(121)
# plt.title("horizontal")
# plt.imshow(PreWittAlogrithm(gray_saber, "horizontal"), cmap="binary")
# plt.axis("off")
# plt.subplot(122)
# plt.title("vertical")
# plt.imshow(PreWittAlogrithm(gray_saber, "vertical"), cmap="binary")
# plt.axis("off")
# plt.show()
原图:
水平边缘:
垂直边缘:
16.梯度Sobel滤波/卷积
代码:
import cv2
from pylab import *
saber = cv2.imread("test03.jpg")
gray_saber = cv2.cvtColor(saber, cv2.COLOR_RGB2GRAY)
# gray_saber = cv2.resize(gray_saber, (200, 200))
def SobelOperator(roi, operator_type):
if operator_type == "horizontal":
sobel_operator = np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]])
elif operator_type == "vertical":
sobel_operator = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]])
else:
raise ("type Error")
result = np.abs(np.sum(roi * sobel_operator))
return result
def SobelAlogrithm(image, operator_type):
new_image = np.zeros(image.shape)
image = cv2.copyMakeBorder(image, 1, 1, 1, 1, cv2.BORDER_DEFAULT)
for i in range(1, image.shape[0] - 1):
for j in range(1, image.shape[1] - 1):
new_image[i - 1, j - 1] = SobelOperator(image[i - 1:i + 2, j - 1:j + 2], operator_type)
new_image = new_image * (255 / np.max(image))
return new_image.astype(np.uint8)
# 显示图像
cv2.imshow("source img", saber)
cv2.imshow("horizontal", SobelAlogrithm(gray_saber, "horizontal"))
cv2.imshow("vertical", SobelAlogrithm(gray_saber, "vertical"))
# 等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()
# plt.subplot(121)
# plt.title("horizontal")
# plt.imshow(SobelAlogrithm(gray_saber, "horizontal"), cmap="binary")
# plt.axis("off")
# plt.subplot(122)
# plt.title("vertical")
# plt.imshow(SobelAlogrithm(gray_saber, "vertical"), cmap="binary")
# plt.axis("off")
# plt.show()
原图:
水平边缘:
垂直边缘:
17.梯度Laplacian滤波/卷积
代码:
import cv2
from pylab import *
saber = cv2.imread("test03.jpg")
# 首先将原图像进行边界扩展,并将其转换为灰度图。
gray_saber = cv2.cvtColor(saber, cv2.COLOR_RGB2GRAY)
# gray_saber = cv2.resize(gray_saber, (200, 200))
def LaplaceOperator(roi, operator_type):
if operator_type == "fourfields":
laplace_operator = np.array([[0, 1, 0], [1, -4, 1], [0, 1, 0]])
elif operator_type == "eightfields":
laplace_operator = np.array([[1, 1, 1], [1, -8, 1], [1, 1, 1]])
else:
raise ("type Error")
result = np.abs(np.sum(roi * laplace_operator))
return result
def LaplaceAlogrithm(image, operator_type):
new_image = np.zeros(image.shape)
image = cv2.copyMakeBorder(image, 1, 1, 1, 1, cv2.BORDER_DEFAULT)
for i in range(1, image.shape[0] - 1):
for j in range(1, image.shape[1] - 1):
new_image[i - 1, j - 1] = LaplaceOperator(image[i - 1:i + 2, j - 1:j + 2], operator_type)
new_image = new_image * (255 / np.max(image))
return new_image.astype(np.uint8)
# 显示图像
cv2.imshow("source img", saber)
cv2.imshow("fourfields", LaplaceAlogrithm(gray_saber, "fourfields"))
cv2.imshow("eightfields", LaplaceAlogrithm(gray_saber, "eightfields"))
# 等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()
原图:
四邻域:
八邻域: