4
社区成员
发帖
与我相关
我的任务
分享
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import pyplot as plt
class HistogramProcessing:
def __init__(self, image_path):
self.image_path = image_path
self.img = cv.imread(self.image_path)
if self.img is None:
raise FileNotFoundError(f"无法读取图像文件: {self.image_path}")
def calculate_1d_histogram(self, use_cv=True):
"""
计算一维直方图
:param use_cv: 是否使用OpenCV计算直方图,默认为True
:return: 直方图数据(如果使用OpenCV计算)或 (直方图数据, 区间边界)(如果使用Numpy计算)
示例:
hist_processor = HistogramProcessing('66.png')
result = hist_processor.calculate_1d_histogram()
"""
if use_cv:
img_gray = cv.cvtColor(self.img, cv.COLOR_BGR2GRAY)
hist = cv.calcHist([img_gray], [0], None, [256], [0, 256])
return hist
else:
img_gray = cv.cvtColor(self.img, cv.COLOR_BGR2GRAY)
hist, bins = np.histogram(img_gray.ravel(), 256, [0, 256])
return hist, bins
def plot_1d_histogram(self, use_cv=True):
"""
绘制一维直方图
:param use_cv: 是否使用OpenCV计算直方图来绘制,默认为True
示例:
hist_processor = HistogramProcessing('66.png')
hist_processor.plot_1d_histogram()
"""
if use_cv:
img_gray = cv.cvtColor(self.img, cv.COLOR_BGR2GRAY)
hist = cv.calcHist([img_gray], [0], None, [256], [0, 256])
plt.plot(hist)
plt.xlim([0, 256])
plt.show()
else:
img_gray = cv.cvtColor(self.img, cv.COLOR_BGR2GRAY)
hist, bins = np.histogram(img_gray.ravel(), 256, [0, 256])
plt.hist(img_gray.ravel(), 256, [0, 256])
plt.show()
def plot_color_histogram(self):
"""
使用Matplotlib绘制彩色图像的直方图
示例:
hist_processor = HistogramProcessing('66.png')
hist_processor.plot_color_histogram()
"""
color = ('b', 'g', 'r')
for i, col in enumerate(color):
histr = cv.calcHist([self.img], [i], None, [256], [0, 256])
plt.plot(histr, color=col)
plt.xlim([0, 256])
plt.show()
def plot_histogram_with_mask(self):
"""
使用OpenCV计算并绘制掩码区域和非掩码区域的直方图
示例:
hist_processor = HistogramProcessing('66.png')
hist_processor.plot_histogram_with_mask()
"""
img_gray = cv.cvtColor(self.img, cv.COLOR_BGR2GRAY)
mask = np.zeros(img_gray.shape[:2], np.uint8)
mask[100:300, 100:400] = 255
masked_img = cv.bitwise_and(img_gray, img_gray, mask=mask)
hist_full = cv.calcHist([img_gray], [0], None, [256], [0, 256])
hist_mask = cv.calcHist([img_gray], [0], mask, [256], [0, 256])
plt.subplot(2, 2, 1), plt.imshow(img_gray, 'gray')
plt.subplot(2, 2, 2), plt.imshow(mask, 'gray')
plt.subplot(2, 2, 3), plt.imshow(masked_img, 'gray')
plt.subplot(2, 2, 4), plt.plot(hist_full), plt.plot(hist_mask)
plt.xlim([0, 256])
plt.show()
def histogram_equalization(self, method='opencv'):
"""
进行直方图均衡化
:param method: 均衡化方法,可选 'opencv' 或 'numpy',默认为 'opencv'
示例:
hist_processor = HistogramProcessing('66.png')
hist_processor.histogram_equalization()
"""
img_gray = cv.cvtColor(self.img, cv.COLOR_BGR2GRAY)
if method == 'opencv':
equ = cv.equalizeHist(img_gray)
res = np.hstack((img_gray, equ))
cv.imwrite('res.png', res)
plt.imshow(res, cmap='gray')
plt.show()
elif method == 'numpy':
hist, bins = np.histogram(img_gray.flatten(), 256, [0, 256])
cdf = hist.cumsum()
cdf_normalized = cdf * float(hist.max()) / cdf.max()
plt.plot(cdf_normalized, color='b')
plt.hist(img_gray.flatten(), 256, [0, 256], color='r')
plt.xlim([0, 256])
plt.legend(('cdf', 'histogram'), loc='upper left')
plt.show()
cdf_m = np.ma.masked_equal(cdf, 0)
cdf_m = (cdf_m - cdf_m.min()) * 255 / (cdf_m.max() - cdf_m.min())
cdf = np.ma.filled(cdf_m, 0).astype('uint8')
img2 = cdf[img_gray]
def clahe_equalization(self, clipLimit=2.0, tileGridSize=(8, 8)):
"""
进行CLAHE(对比度受限的自适应直方图均衡)
:param clipLimit: 对比度限制,默认为2.0
:param tileGridSize: 瓦片网格大小,默认为(8, 8)
示例:
hist_processor = HistogramProcessing('66.png')
hist_processor.clahe_equalization()
"""
img_gray = cv.cvtColor(self.img, cv.COLOR_BGR2GRAY)
clahe = cv.createCLAHE(clipLimit=clipLimit, tileGridSize=tileGridSize)
cl1 = clahe.apply(img_gray)
cv.imwrite('clahe_2.jpg', cl1)
plt.imshow(cl1, cmap='gray')
plt.show()
def calculate_2d_histogram(self, use_cv=True):
"""
计算二维直方图
:param use_cv: 是否使用OpenCV计算二维直方图,默认为True
:return: 二维直方图数据(如果使用OpenCV计算)或 (二维直方图数据, x区间边界, y区间边界)(如果使用Numpy计算)
示例:
hist_processor = HistogramProcessing('66.png')
result = hist_processor.calculate_2d_histogram()
"""
hsv = cv.cvtColor(self.img, cv.COLOR_BGR2HSV)
if use_cv:
hist = cv.calcHist([hsv], [0, 1], None, [180, 256], [0, 180, 0, 256])
return hist
else:
h = hsv[:, :, 0]
s = hsv[:, :, 1]
hist, xbins, ybins = np.histogram2d(h.ravel(), s.ravel(), [180, 256], [[0, 180], [0, 256]])
return hist, xbins, ybins
def plot_2d_histogram(self, use_cv=True):
"""
绘制二维直方图
:param use_cv: 是否使用OpenCV计算的直方图来绘制,默认为True
示例:
hist_processor = HistogramProcessing('66.png')
hist_processor.plot_2d_histogram()
"""
hsv = cv.cvtColor(self.img, cv.COLOR_BGR2HSV)
if use_cv:
hist = cv.calcHist([hsv], [0, 1], None, [180, 256], [0, 180, 0, 256])
plt.imshow(hist, interpolation='nearest')
plt.show()
else:
h = hsv[:, :, 0]
s = hsv[:, :, 1]
hist, xbins, ybins = np.histogram2d(h.ravel(), s.ravel(), [180, 256], [[0, 180], [0, 256]])
plt.imshow(hist, interpolation='nearest')
plt.show()
def histogram_back_projection(self, target_path=None):
"""
进行直方图反投影
:param target_path: 目标图像路径,如果为None则使用初始化时的图像路径,默认为None
示例:
hist_processor = HistogramProcessing('66.png')
hist_processor.histogram_back_projection()
"""
if target_path is None:
target_path = self.image_path
roi = cv.imread(self.image_path)
hsv = cv.cvtColor(roi, cv.COLOR_BGR2HSV)
target = cv.imread(target_path)
hsvt = cv.cvtColor(target, cv.COLOR_BGR2HSV)
roihist = cv.calcHist([hsv], [0, 1], None, [180, 256], [0, 180, 0, 256])
cv.normalize(roihist, roihist, 0, 255, cv.NORM_MINMAX)
dst = cv.calcBackProject([hsvt], [0, 1], roihist, [0, 180, 0, 256], 1)
disc = cv.getStructuringElement(cv.MORPH_ELLIPSE, (5, 5))
cv.filter2D(dst, -1, disc, dst)
ret, thresh = cv.threshold(dst, 50, 255, 0)
thresh = cv.merge((thresh, thresh, thresh))
res = cv.bitwise_and(target, thresh)
res = np.vstack((target, thresh, res))
cv.imwrite('res.jpg', res)