OpenCV判断颜色相似图片:基于直方图均衡化的BGR通道相似度计算

沿途有光
沿途有光
发布时间:2026-10-15| 5人浏览过
原创

本文介绍利用OpenCV判断图片颜色相似度的方法。通过对比原始BGR直方图相似度低的缺陷,提出将图像转换至HSV通道并对V(明度)通道进行均衡化处理,再转回BGR通道计算相似度的方案。实验表明,该方法能有效提升颜色相近图片的相似度评分,适用于文章配图突兀性检测等场景。

问题描述

项目需求涉及评估文章内配图是否显得突兀。

素材准备

从网络选取了4张测试图片:

观察可知,前3张图片在色彩和阅读体验上具有相似性,而最后一张则明显不同。

若仅对图片进行缩放以加速处理,并使用BGR通道生成直方图计算相似度:

结果显示,仅第一张与第二张图片的相似度超过0.5,而第二、三张以及第三、四张图片之间的相似度均低于或等于0.1。

思考方法

经分析,判断图片颜色相似的本质在于直方图分布形状的相似性,而非分布位置(如偏左或偏右、偏亮或偏暗)。即使图像亮度不同,只要分布形状一致,仍可视为相似。

基于此思路,首先尝试对BGR及HLS三个通道独立进行均衡化处理,以验证判断分布形状的可行性。然而,独立均衡化导致对不同图片的分辨能力下降。由此推断,应对亮度进行平均化均衡,同时关联影响其他通道的变化。

最终确定的方案如下:

  1. 首先将图片缩放至统一尺寸,以提升运算效率。
  2. 将图像从BGR空间转换至HSV空间(实验表明,HSV通道效果优于HLS通道)。
  3. 对HSV空间中的V(明度)通道执行均衡化处理(equalizeHist)。
  4. 再将图像从HSV空间转换回BGR空间,从而在均衡亮度的同时影响其他通道。
  5. 最后,利用BGR通道计算相似度,若结果大于0.5,则判定为相似。

测试结果

处理后的结果显示,第一、二张图片以及第二、三张图片之间的相似度已提升至0.7以上,而第三、四张图片的相似度约为0.4,达到了初步目标。

不足之处

  • 仅对V通道进行了均衡化探索,未深入研究其他通道的潜在关联。
  • 第三、四张图片处理后的相似度仍偏高,需进一步优化以降低。

代码


import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt


def create_rgb_hist(image):
  """"创建 RGB 三通道直方图(直方图矩阵)"""
  h, w, c = image.shape
  # 创建一个(16*16*16,1)的初始矩阵,作为直方图矩阵
  # 16*16*16的意思为三通道每通道有16个bins
  rgbhist = np.zeros([16 * 16 * 16, 1], np.float32)
  bsize = 256 / 16
  for row in range(h):
    for col in range(w):
      b = image[row, col, 0]
      g = image[row, col, 1]
      r = image[row, col, 2]
      # 人为构建直方图矩阵的索引,该索引是通过每一个像素点的三通道值进行构建
      index = int(b / bsize) * 16 * 16 + int(g / bsize) * 16 + int(r / bsize)
      # 该处形成的矩阵即为直方图矩阵
      rgbhist[int(index), 0] += 1
  plt.ylim([0, 10000])
  plt.grid(color='r', linestyle='--', linewidth=0.5, alpha=0.3)
  return rgbhist


def hist_compare(hist1, hist2):
  """直方图比较函数"""
  '''# 创建第一幅图的rgb三通道直方图(直方图矩阵)
  hist1 = create_rgb_hist(image1)
  # 创建第二幅图的rgb三通道直方图(直方图矩阵)
  hist2 = create_rgb_hist(image2)'''
  # 进行三种方式的直方图比较
  match1 = cv.compareHist(hist1, hist2, cv.HISTCMP_BHATTACHARYYA)
  match2 = cv.compareHist(hist1, hist2, cv.HISTCMP_CORREL)
  match3 = cv.compareHist(hist1, hist2, cv.HISTCMP_CHISQR)
  print("巴氏距离:%s, 相关性:%s, 卡方:%s" % (match1, match2, match3))


def handle_img(img):
  img = cv.resize(img, (100, 100))
  img = cv.cvtColor(img, cv.COLOR_BGR2HSV)
  img[:, :, 2] = cv.equalizeHist(img[:, :, 2])
  img = cv.cvtColor(img, cv.COLOR_HSV2BGR)
  return img


img1 = cv.imread("1.jpg")
img1 = handle_img(img1)
cv.imshow("img1", img1)

img2 = cv.imread("2.jpg")
img2 = handle_img(img2)
cv.imshow("img2", img2)

img3 = cv.imread("3.jpg")
img3 = handle_img(img3)
cv.imshow("img3", img3)

img4 = cv.imread("4.jpg")
img4 = handle_img(img4)
cv.imshow("img4", img4)

hist1 = create_rgb_hist(img1)
hist2 = create_rgb_hist(img2)
hist3 = create_rgb_hist(img3)
hist4 = create_rgb_hist(img4)

plt.subplot(1, 4, 1)
plt.title("hist1")
plt.plot(hist1)
plt.subplot(1, 4, 2)
plt.title("hist2")
plt.plot(hist2)
plt.subplot(1, 4, 3)
plt.title("hist3")
plt.plot(hist3)
plt.subplot(1, 4, 4)
plt.title("hist4")
plt.plot(hist4)

hist_compare(hist1, hist2)
hist_compare(hist2, hist3)
hist_compare(hist3, hist4)

plt.show()

cv.waitKey(0)
cv.destroyAllWindows()

至此,关于利用OpenCV判断颜色相似图片的示例代码介绍完毕。如需了解更多OpenCV判断相似图片的内容,请查阅本站往期文章或继续浏览后续内容,感谢支持!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。