opencv 彩色图像equalizeHist注意事项

对彩色图像进行直方图均衡化,一般是通过对HSV色彩空间的V通道进行直方图均衡化,再合并H,S,V三个通道后转化为RGB空间。(其实V通道简单来说就是图像明暗通道,增加V通道值的效果等同于windows照片编辑中的光线调整,如下图,S通道则相当于windows照片编辑中的颜色调整(饱和度))

彩色图像直方图均衡化示例代码为:

import cv2
import numpy as np
import matplotlib.pyplot as plt

if __name__ == '__main__':
    img = cv2.imread("pic.jpg")
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    h, s, v = cv2.split(hsv)
    v2 = cv2.equalizeHist(v)
    img2 = cv2.merge([h, s, v2])
    rgb = cv2.cvtColor(img2, cv2.COLOR_HSV2RGB)
    plt.imshow(rgb)
    plt.show()

但是一定要注意应用目的,在图像整体都是偏亮时,这样直方图均衡化会导致图像最终颜色失真。

遇到的问题描述:

Easypr项目中通过颜色定位车牌(colorMatch函数),但是却无法正确识别出颜色,效果如下:

将图片裁剪后却能识别(裁掉背景区域),效果如下:

最终检查,问题出在代码中的直方图均衡化:在不存在较暗区域的图片中进行v通道的直方图均衡化后,会导致原先符合V阈值的蓝色区域,其V值被拉伸到了低于阈值的部分,因此颜色识别失败。(原项目中的车牌图像数据集所包含的场景大多为车身+周围环境,但是目前我的实验数据集有一部分是只有车牌+车牌附近的区域,因此出现了这种问题)

 

原项目有问题部分的代码(core_func.hpp->colorMatch())如下,在注释equalizeHist那一行之后,蓝色车牌部分能够被正确识别:

	Mat colorMatch(const Mat &src, Mat &match, const Color r,
		const bool adaptive_minsv) {
                /*去掉了很多其余代码*/
		
		/*阈值设定...*/

		Mat src_hsv;

		// convert to HSV space
		cvtColor(src, src_hsv, CV_BGR2HSV);

		std::vector<cv::Mat> hsvSplit;
		split(src_hsv, hsvSplit);
		// 这种操作不适用于所有图片
		equalizeHist(hsvSplit[2], hsvSplit[2]); 
		merge(hsvSplit, src_hsv);

		
		for (int i = 0; i < nRows; ++i) {
			p = src_hsv.ptr<uchar>(i);
			for (int j = 0; j < nCols; j += 3) {
				int H = int(p[j]);      // 0-180
				int S = int(p[j + 1]);  // 0-255
				int V = int(p[j + 2]);  // 0-255

				bool colorMatched = false;
				if (H > min_h && H < max_h) {

                    // 同理,因为equalizeHist不适用,因此对V进行比较意义也不大
                    // 因为有些拍照环境光线都很暗
					if ((S > min_sv && S < max_sv) && (V > min_sv && V < max_sv))
						colorMatched = true;
				}

				if (colorMatched == true) {
					p[j] = 0;
					p[j + 1] = 0;
					p[j + 2] = 255;
				}
				else {
					p[j] = 0;
					p[j + 1] = 0;
					p[j + 2] = 0;
				}
			}
		}

		Mat src_grey;
		std::vector<cv::Mat> hsvSplit_done;
		split(src_hsv, hsvSplit_done);
		src_grey = hsvSplit_done[2];

		match = src_grey;

		return src_grey;
	}

 

 

 

 

 

 

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值