zoukankan      html  css  js  c++  java
  • 【图像处理】基于OpenCV底层实现的直方图匹配

    image processing 系列:

    1. 【图像处理】图片旋转
    2. 【图像处理】高斯滤波、中值滤波、均值滤波

    直方图匹配算法。又称直方图规定化。简单说。就是依据某函数、或者另外一张图片的引导,使得原图改变。

    感觉解释的最好的是:http://www.360doc.com/content/13/1106/16/10724725_327179043.shtml

    完整代码:github (里面同一时候包括OSTU / 大津算法、直方图均衡化等算法,还包括两种測试图片)。

    由于我个人兴趣爱好(放P就是老师逼的。

    。。)。不同意使用 OpenCV 封装好的直方图函数。

    依据实例解说,了解了直方图匹配算法底层的操作(多说一句,这个样例能够是我见过最好的直方图匹配算法解说,也是非常难见的此算法的样例,必读)。

    注:实例解说中 0->3 的意义是,原图中灰度级为 0 的像素点所有转化为原图中的 3 灰度级。


    上代码(当中,srcImg 是原图。dstImg 是须要匹配的图,flag 标记两者是 RGB  图还是灰度图):

    cv::Mat ycMatchHist(cv::Mat srcImg, cv::Mat dstImg, int flag)
    {
    	// ****** 假设是 RGB 图片则转为灰度图片操作 ******
    	Mat out(srcImg);
    	if (flag == YC_RGB)
    	{
    		cvtColor(srcImg, out, CV_BGR2GRAY);
    	}
    	else if (flag == YC_GRAY)
    	{
    	}
    	int grayLevel[colvl];
    	for(int i=0; i<colvl; i++)	grayLevel[i] = i;
    
    	int grayArr[colvl];
    	int srcRow = srcImg.rows;
    	int srcCol = srcImg.cols;
    	int dstRow = dstImg.rows;
    	int dstCol = dstImg.cols;
    	float srcCdfArr[colvl]  = {0.f};
    	float dstCdfArr[colvl]  = {0.f};
    	float tmp;
    
    	// *** 求解源图片的累积直方图(概率)分布 *** 
    	memset(grayArr, 0, sizeof(grayArr));
    	for(size_t nrow = 0; nrow < srcRow; nrow++)  
           for(size_t ncol = 0; ncol < srcCol; ncol++)
    	   {
    		   int tag = srcImg.at<uchar>(nrow, ncol);
    		   grayArr[tag]++;
    	   }
    
    	tmp = 0;
    	for(int i=0; i<colvl; i++)
    	{
    		tmp += grayArr[i];
    		srcCdfArr[i] = tmp / (srcRow * srcCol);
    		// std::cout<<srcCdfArr[i]<<std::endl;
    	}
    
    	// *** 求解目标图片的累积直方图(概率)分布 *** 
    	memset(grayArr, 0, sizeof(grayArr));
    	for(size_t nrow = 0; nrow < dstRow; nrow++)  
           for(size_t ncol = 0; ncol < dstCol; ncol++)
    	   {
    		   int tag = dstImg.at<uchar>(nrow, ncol);
    		   grayArr[tag]++;
    	   }
    
    	tmp = 0;
    	for(int i=0; i<colvl; i++)
    	{
    		tmp += grayArr[i];
    		dstCdfArr[i] = tmp / (dstRow * dstCol);
    	}
    
    	// *** 直方图匹配算法 ***
    	int histMap[colvl];
    	int minTag;
    	for(int i=0; i<colvl; i++)
    	{
    		float minMap = 10.f;
    		for(int j=0; j<colvl; j++)
    		{
    			if (minMap > abs(srcCdfArr[i] - dstCdfArr[j]))
    			{
    				minMap = abs(srcCdfArr[i] - dstCdfArr[j]);
    				minTag = j;
    			}
    		}
    		histMap[i] = minTag;
    	}
    
    	for(size_t nrow = 0; nrow < out.rows; nrow++)  
           for(size_t ncol = 0; ncol < out.cols; ncol++)
    	   {
    		   int tag = out.at<uchar>(nrow, ncol);
    		   out.at<uchar>(nrow, ncol) = histMap[tag];
    	   }
    
    	return out;
    }

    实验结果例如以下:

    原图为

    须要匹配的图是

    终于输出的是图

    匹配图片的灰度累积直方图为:

    终于输出的灰度累积直方图为:

    两者非常接近了,证明匹配算法是可行的(当然假设我说错了,欢迎打脸。共同进步哈哈~)

  • 相关阅读:
    Kerberos协议
    闪电咂摸软件隐喻与建模
    hibernate set集合配置排序
    java小游戏2048实现
    java版餐饮管理系统
    使用HTML5对网页元素进行拖动
    投票网站如何防止机器刷票
    JAVAEE 企业网站建设发布与网站备案流程
    JavaScript 离开页面提醒,在编辑页面常用的关闭提醒功能
    java Swing局域网聊天软件+ 情侣电脑钢琴
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5409488.html
Copyright © 2011-2022 走看看