http://www.dakaren.com/blog/post/23.html
OPENCV下针对IplImage实现图像增强处理 字体大小: 小 中 大 作者: admin | 分类: 图像技术 | 浏览: 181| 评论: 仅有1条 因为使用的摄像头图像质量很差,不能直接用做分割等后续的处理,需要根据直方图进行图像增强,OPENCV没有现成的方法,只有自己想办法了。 参考了网上文章 http://www.xiaozhou.net/ReadNews.asp?NewsID=771 原理就是利用直方图统计分布,将图像灰度的域值拉伸到0-255,原来网上的代码有些问题,而且是使用bmp的,我就改成了IplImage了,于是在OPENCV实现了这个功能,感觉效果不错,可以看到昏暗的图像可以增强的很好。结果如下: WW_RETURN HumanMotion::ImageStretchByHistogram(IplImage *src,IplImage *dst)/**//************************************************* Function: Description: 因为摄像头图像质量差,需要根据直方图进行图像增强, 将图像灰度的域值拉伸到0-255 Calls: Called By: Input: 单通道灰度图像 Output: 同样大小的单通道灰度图像 Return: Others: http://www.xiaozhou.net/ReadNews.asp?NewsID=771 DATE: 2007-1-5*************************************************/{ //p[]存放图像各个灰度级的出现概率; //p1[]存放各个灰度级之前的概率和,用于直方图变换; //num[]存放图象各个灰度级出现的次数; assert(src->width==dst->width); float p[256],p1[256],num[256]; //清空三个数组 memset(p,0,sizeof(p)); memset(p1,0,sizeof(p1)); memset(num,0,sizeof(num)); int height=src->height; int width=src->width; long wMulh = height * width; //求存放图象各个灰度级出现的次数 // to do use openmp for(int x=0;x<width;x++) { for(int y=0;yimageData + src->widthStep*y))[x]; num[v]++; } } //求存放图像各个灰度级的出现概率 for(int i=0;i<256;i++) { p[i]=num[i]/wMulh; } //求存放各个灰度级之前的概率和 for(int i=0;i<256;i++) { for(int k=0;k<=i;k++) p1[i]+=p[k]; } //直方图变换 // to do use openmp for(int x=0;x<width;x++) { for(int y=0;yimageData + src->widthStep*y))[x]; ((uchar*)(dst->imageData + dst->widthStep*y))[x]= p1[v]*255+0.5; } } return WW_OK;}本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/hardVB/archive/2007/01/05/1474880.aspx以下为完整代码:// Open17.cpp : Defines the entry point for the console application. http://blog.csdn.net/soarnic/archive/2008/09/26/2985116.aspx// http://blog.csdn.net/hardVB/archive/2007/01/05/1474880.aspx #include "stdafx.h" #include "stdafx.h" #include "cv.h"#include "highgui.h" /*************************************************Function: Description: 因为摄像头图像质量差,需要根据直方图进行图像增强,将图像灰度的域值拉伸到0-255Calls: Called By: Input: 单通道灰度图像 Output: 同样大小的单通道灰度图像Return: Others: http://www.xiaozhou.net/ReadNews.asp?NewsID=771DATE: 2007-1-5*************************************************/bool ImageStretchByHistogram(IplImage *src,IplImage *dst){ // p[]存放图像各个灰度级的出现概率; // p1[]存放各个灰度级之前的概率和,用于直方图变换; // num[]存放图象各个灰度级出现的次数; assert(src->width == dst->width); float p[256], p1[256], num[256]; // 清空三个数组 memset(p, 0, sizeof(p)); memset(p1, 0, sizeof(p1)); memset(num, 0, sizeof(num)); int height = src->height; int width = src->width; long wMulh = height * width; int i, x, y, k; // 求存放图象各个灰度级出现的次数 // to do use openmp for(x = 0; x < width; x++) { for(y = 0; y< height; y++) { uchar v = ((uchar*)(src->imageData + src->widthStep * y))[x]; num[v]++; } } // 求存放图像各个灰度级的出现概率 for(i = 0; i < 256; i++) { p[i] = num[i] / wMulh; } // 求存放各个灰度级之前的概率和 for(i = 0; i < 256; i++) { for(k = 0; k <= i; k++) p1[i] += p[k]; } // 直方图变换 // to do use openmp for(x = 0; x < width; x++) { for(y = 0; y < height; y++) { uchar v = ((uchar*)(src->imageData + src->widthStep * y))[x]; ((uchar*)(dst->imageData + dst->widthStep*y))[x] = p1[v] * 255 + 0.5; } } return true; } int main(int argc, char* argv[]){ IplImage * pImg; pImg = cvLoadImage("c:\\o_Image_Stretch.jpg", -1); // 创建一个灰度图像 IplImage* GrayImage = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1); IplImage* dstGrayImage = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1); cvCvtColor(pImg, GrayImage, CV_BGR2GRAY); ImageStretchByHistogram(GrayImage, dstGrayImage); cvNamedWindow("dstGrayImage", 1); // 创建窗口 cvNamedWindow("GrayImage", 1); // 创建窗口 cvShowImage("dstGrayImage", dstGrayImage); // 显示图像 cvShowImage("GrayImage", GrayImage); // 显示图像 cvWaitKey(0); // 等待按键 cvDestroyWindow( "dstGrayImage" ); // 销毁窗口 cvDestroyWindow( "GrayImage" ); // 销毁窗口 cvReleaseImage(&pImg); // 释放图像 cvReleaseImage(&GrayImage); // 释放图像 cvReleaseImage(&dstGrayImage); // 释放图像}