【OpenCV笔记】图像预处理

对输入的任意一张图片要做预处理,本文的预处理主要有:灰度化、尺寸归一化、灰度直方图均衡化。

1、改变图片大小

(1)创建新图像

c函数接口:

 IplImage* cvCreateImage(CvSize size, int depth, int channels);

参数:

  • size – Image width and height 图像的大小
  • depth – Bit depth of image elements. 图像的深度,可以是IPL_DEPTH8U,IPL_DEPTH_16U等
  • channels – Number of channels per pixel. This function only creates images with interleaved channels. 图像的通道数

(2)图像变换大小

c函数接口:

void cvResize(const CvArr* src, CvArr* dst, int interpolation=CV_INTER_LINEAR )

参数:

  • src – input image.
  • dst – output image; the type of dst is the same as of src
  • interpolation –表示插值方法

    interpolation method:

    • INTER_NEAREST - a nearest-neighbor interpolation最近邻插值
    • INTER_LINEAR - a bilinear interpolation (used by default)双线性插值(缺省使用)
    • INTER_AREA - resampling using pixel area relation. It may be a preferred method for image decimation, as it gives moire’-free results. But when the image is zoomed, it is similar to the INTER_NEAREST method.使用像素关系重采样。当图片缩小时,该方法可以避免波纹出现。
    • INTER_CUBIC - a bicubic interpolation over 4x4 pixel neighborhood立方插值

(3)缩放图像示例
void show_resized_image(float fScale)
{
	const char *pstrSrcImg = "yueyu.jpg";
	const char *pstrDstImg = "yueyu_resize.jpg";
	const char *pstrSrcWin = "Source Image";
	const char *pstrDstWin = "Resize Image";

	//double fScale = 0.5;
	CvSize dstSize;

	IplImage *pSrcImg = cvLoadImage(pstrSrcImg, CV_LOAD_IMAGE_UNCHANGED);
	IplImage *pDstImg = NULL;

	//calculate the size of the objective image
	dstSize.height = pSrcImg->height * fScale;
	dstSize.width = pSrcImg->width * fScale;
	
	//create the resized image
	pDstImg = cvCreateImage(dstSize, pSrcImg->depth, pSrcImg->nChannels);
	cvResize(pSrcImg, pDstImg, CV_INTER_AREA);
	
	//show the image
	cvShowImage(pstrSrcWin, pSrcImg);
	cvShowImage(pstrDstWin, pDstImg);

	//wait for the key
	cvWaitKey(0);

	//save the image
	cvSaveImage(pstrDstImg, pDstImg);

	cvDestroyWindow(pstrSrcWin);
	cvDestroyWindow(pstrDstWin);
	cvReleaseImage(&pSrcImg);
	cvReleaseImage(&pDstImg);
}

结果如图:
【OpenCV笔记】图像预处理_第1张图片

2、灰度直方图与灰度直方图均衡化
灰度直方图是指对图像的灰度信息进行统计,而灰度直方图均衡化则是使图片的颜色分布均衡,增强对比度,使图片从一个亮度分布映射到另一个更宽、更理想的亮度分布。
(1)创建直方图
c函数接口:
CvHistogram* cvCreateHist(int dims, int* sizes, int type, float** ranges=NULL, int uniform=1 )

参数:
  • dims – Number of histogram dimensions.直方图维数,灰度图为1
  • sizes – Array of the histogram dimension sizes.直方图维数的大小范围,灰度图是256
  • type – Histogram representation format. CV_HIST_ARRAY means that the histogram data is represented as a multi-dimensional dense array CvMatND. CV_HIST_SPARSE means that histogram data is represented as a multi-dimensional sparse array CvSparseMat.直方图类型,CV_HIST_ARRAY表示直方图数据表示为多维密集数组,为CV_HIST_TREE表示直方图数据表示为多维稀疏数组。
  • ranges – Array of ranges for the histogram bins. Its meaning depends on the uniform parameter value. The ranges are used when the histogram is calculated or backprojected to determine which histogram bin corresponds to which value/tuple of values from the input image(s).直方图维数尺寸的数组
  • uniform – Uniformity flag. 归一化标识,通常使用默认值

直方图的数据结构如下所示:

typedef struct CvHistogram
{
    int     type;
    CvArr*  bins;
    float   thresh[CV_MAX_DIM][2];  /* For uniform histograms. */
    float** thresh2;                /* For non-uniform histograms. */
    CvMatND mat;     /* Embedded matrix header for array histograms. */
}CvHistogram;


(2)计算直方图
c函数接口:
void cvCalcHist(IplImage** image, CvHistogram* hist, int accumulate=0, const CvArr* mask=NULL )
参数:
  • images – Source arrays. They all should have the same depth, CV_8U or CV_32F , and the same size. Each of them can have an arbitrary number of channels.
  • mask – Optional mask. If the matrix is not empty, it must be an 8-bit array of the same size as images[i]. The non-zero mask elements mark the array elements counted in the histogram. 确定输入图像的那个像素被计数
  • hist – Output histogram, which is a dense or sparse dims -dimensional array. 输出的直方图指针
  • accumulate – Accumulation flag. If it is set, the histogram is not cleared in the beginning when it is allocated. This feature enables you to compute a single histogram from several sets of arrays, or to update the histogram in time. 累计标识。如果设置,则直方图在开始时不被清零。这个特征保证可以为多个图像计算一个单独的直方图,或者在线更新直方图

(3)直方图均衡化,归一化图像亮度、增强对比度
c函数接口:
void cvEqualizeHist(const CvArr* src, CvArr* dst)
参数:
  • src – Source 8-bit single channel image.
  • dst – Destination image of the same size and type as src
(4)直方图均衡化示例
void FillWhite(IplImage *pImage)  
{  
    cvRectangle(pImage, cvPoint(0, 0), cvPoint(pImage->width, pImage->height), CV_RGB(255, 255, 255), CV_FILLED);  
}  

//create histogram of gray image 
CvHistogram* CreateGrayImageHist(IplImage **ppImage)  
{  
    int nHistSize = 256;  
    float fRange[] = {0, 255};  //gray scale   
    float *pfRanges[] = {fRange};    
    CvHistogram *pcvHistogram = cvCreateHist(1, &nHistSize, CV_HIST_ARRAY, pfRanges);  
    cvCalcHist(ppImage, pcvHistogram);  
    return pcvHistogram;
}

IplImage *CreateHistImage(int nImageWidth, int nImageHeight, int nScale, CvHistogram *pcvHistogram)
{
	IplImage *pHistImg = cvCreateImage(cvSize(nImageWidth*nScale, nImageHeight),IPL_DEPTH_8U,1);
	FillWhite(pHistImg);

	//calculate the max histogram value
	float fMaxHistValue = 0;
	cvGetMinMaxHistValue(pcvHistogram, NULL, &fMaxHistValue, NULL, NULL);

	//draw each histogram block
	int i;
	for(i = 0;i < nImageWidth;i++){
		float fHistValue = cvQueryHistValue_1D(pcvHistogram, i);
		int nRealHeight = cvRound((fHistValue/fMaxHistValue) * nImageHeight);//height to draw
		cvRectangle(pHistImg,
			cvPoint(i*nScale,nImageHeight-1),
			cvPoint((i+1)*nScale-1,nImageHeight-nRealHeight),
			cvScalar(i,0,0,0),
			CV_FILLED);
	}
	return pHistImg;
}

void show_histogram()
{
	const char *pstrGrayWin = "Gray Image";
	const char *pstrHistWin = "Histogram Image";

	IplImage *pGrayImg = cvLoadImage("yueyu.jpg", CV_LOAD_IMAGE_GRAYSCALE);

	//gray histogram
	CvHistogram *pcvHist = CreateGrayImageHist(&pGrayImg);

	int nHistWidth = 255;
	int nHistHeight = 200;
	int nScale = 3;
	IplImage *pHistImg = CreateHistImage(nHistWidth,nHistHeight,nScale,pcvHist);

	//show
	cvNamedWindow(pstrGrayWin, CV_WINDOW_AUTOSIZE);
	cvNamedWindow(pstrHistWin, CV_WINDOW_AUTOSIZE);
	cvShowImage(pstrGrayWin, pGrayImg);
	cvShowImage(pstrHistWin, pHistImg);

	//wait for key
	cvWaitKey(0);

	cvReleaseHist(&pcvHist);

	cvDestroyWindow(pstrGrayWin);
	cvDestroyWindow(pstrHistWin);
	cvReleaseImage(&pGrayImg);
	cvReleaseImage(&pHistImg);
}

void show_gray_equalize()
{
	const char *pstrGrayWin = "Gray Image";
	const char *pstrGrayEqualWin = "Gray Image(Equalized)";
	const char *pstrHistWin = "Histogram Image";
	const char *pstrHistEqualWin = "Histogram Image(Equalized)";

	IplImage *pGrayImg = cvLoadImage("yueyu.jpg", CV_LOAD_IMAGE_GRAYSCALE);
	IplImage *pGrayEqualImg = cvCreateImage(cvGetSize(pGrayImg),IPL_DEPTH_8U,1);

	//gray histogram
	CvHistogram *pcvHist = CreateGrayImageHist(&pGrayImg);

	int nHistWidth = 255;
	int nHistHeight = 160;
	int nScale = 2;
	IplImage *pHistImg = CreateHistImage(nHistWidth,nHistHeight,nScale,pcvHist);

	//gray equalize
	cvEqualizeHist(pGrayImg, pGrayEqualImg);
	CvHistogram *pcvHistEqual = CreateGrayImageHist(&pGrayEqualImg);
	IplImage *pHistEqualImg = CreateHistImage(nHistWidth,nHistHeight,nScale,pcvHistEqual);

	//show
	cvNamedWindow(pstrGrayWin, CV_WINDOW_AUTOSIZE);
	cvNamedWindow(pstrHistWin, CV_WINDOW_AUTOSIZE);
	cvNamedWindow(pstrGrayEqualWin, CV_WINDOW_AUTOSIZE);
	cvNamedWindow(pstrHistEqualWin, CV_WINDOW_AUTOSIZE);
	cvShowImage(pstrGrayWin, pGrayImg);
	cvShowImage(pstrHistWin, pHistImg);
	cvShowImage(pstrGrayEqualWin, pGrayEqualImg);
	cvShowImage(pstrHistEqualWin, pHistEqualImg);

	//wait for key
	cvWaitKey(0);

	cvReleaseHist(&pcvHist);
	cvReleaseHist(&pcvHistEqual);

	cvDestroyWindow(pstrGrayWin);
	cvDestroyWindow(pstrHistWin);
	cvDestroyWindow(pstrGrayEqualWin);
	cvDestroyWindow(pstrHistEqualWin);
	cvReleaseImage(&pGrayImg);
	cvReleaseImage(&pHistImg);
	cvReleaseImage(&pGrayEqualImg);
	cvReleaseImage(&pHistEqualImg);
}

结果如图:
【OpenCV笔记】图像预处理_第2张图片

转载请标明出处,原文地址:http://blog.csdn.net/jasonding1354/article/details/38061171

你可能感兴趣的:(opencv,图像预处理)