opencv初探(二)——直方图均衡化与双线性插值缩放

来源:互联网 发布:盗版玩家 知乎 编辑:程序博客网 时间:2024/06/05 02:12

这两种算法均基于上一篇所提到的图像像素遍历,通过对每个像素进行相应操作,达到总体上的目的。

一、直方图均衡化

直方图均衡化是增强图像对比度的有效方法。通过对各像素频率的统计来重新分配该像素对应的新像素,但要保证像素之间的大小关系不能翻转,是以采取累积频率来分配像素。

void equalHist(Mat inputImage, Mat &outputImage){int rowNumber = inputImage.rows;int colNumber = inputImage.cols;int total = rowNumber*colNumber;outputImage = Mat(rowNumber, colNumber, CV_8UC1);int freq[256] = { 0 };//各像素出现次数for (int i = 0; i < rowNumber; i++){uchar *pixel_adress = inputImage.ptr<uchar>(i);uchar *pixel_adress2 = outputImage.ptr<uchar>(i);for (int j = 0; j < colNumber; j++){freq[int(pixel_adress[j])] += 1;//对应次数+1//cout << "pixel: " << int(pixel_adress[j]) << endl;}}double freq2[256] = { 0 };//各像素出现频率累积,从0到255freq2[0] = double(freq[0]) / total;//cout <<"freq[255]:"<<freq[255]<< " freq[0]:" << freq[0] << " freq2[0]:" << freq2[0] << endl;for (int j = 1; j < 256; j++){freq2[j] = freq2[j - 1] + double(freq[j]) / total;}//cout <<"freq2[255]:"<<freq2[255]<< " freq2[0]:" << freq2[0] << " freq2[0]:" << freq2[0] << endl;uchar pixel[256] = { 0 };//各像素根据累积频率对应的新像素for (int k = 0; k < 256; k++){pixel[k] = uchar(freq2[k] * 256);}for (int i = 0; i < rowNumber; i++){uchar *in_pixel = inputImage.ptr<uchar>(i);uchar *out_pixel = outputImage.ptr<uchar>(i);for (int j = 0; j < colNumber; j++){out_pixel[j] = pixel[int(in_pixel[j])];}}imshow("out_pixel", outputImage);imwrite("out_pixel.jpg", outputImage);}


、双线性插值图片缩放

图片缩放有多种不同的算法,可根据目的相应的选择。双线性插值法比较简单而且效果也不错。该算法中根据缩放比例,从原图的像素中进行抽样组成新图像的像素。其中需要重点注意整数小数之间的转换以及像素之间对应的位置关系。

void myResize( Mat inputImage, Mat &outputImage, const double onRows ,const double onCols){//双线性插值法缩放图片int rowNum = int(inputImage.rows*onRows);int colNum = int(inputImage.cols*onCols);outputImage = Mat(rowNum, colNum,inputImage.type());for (int i = 0; i < rowNum; i++){double cof[6] = { 0 };double sampleRow = (double(i))/onRows;uchar *pixel_adress2 = outputImage.ptr<uchar>(i);//目的像素行首地址for (int j = 0; j < colNum; j++){double sampleCol = (double(j)) / onCols;uchar *pixel_adress = inputImage.ptr<uchar>(int(sampleRow));//源像素行首地址uchar *pixel_adress3;if ((int(sampleRow) + 1) == rowNum){ pixel_adress3 = inputImage.ptr<uchar>(int(sampleRow) - 1);}else  pixel_adress3 = inputImage.ptr<uchar>(int(sampleRow) + 1);//下一行源像素行首地址//cout << int(sampleRow) + 1 << " rowNum: " << rowNum << endl;cof[4] = sampleRow - (int)sampleRow;//tcof[5] = sampleCol - (int)sampleCol;//ucof[0] = (1 - cof[4])*(1 - cof[5]);//(1-t)*(1-u)cof[1] = cof[4] * (1 - cof[5]);//t*(1-u)cof[2] = (1 - cof[4])*cof[5];//(1-t)*ucof[3] = cof[4] * cof[5];//t*ufor (int k = 0; k<outputImage.channels(); k++)//对每个像素进行操作{pixel_adress2[j*3+k] = cof[0] * pixel_adress[int(sampleCol)*3+k] + cof[1] * pixel_adress[int(sampleCol)*3 + k] +cof[2] * pixel_adress3[int(sampleCol)*3+k] + cof[3] * pixel_adress3[int(sampleCol)*3 + k];//pixel_adress2[j] = uchar(cof[0] * inputImage.at<uchar>((int)sampleRow, (int)sampleCol)) + cof[1] * inputImage.at<uchar>((int)sampleRow, (int)sampleCol  + 1)//+ cof[2] * inputImage.at<uchar>((int)sampleRow + 1, (int)sampleCol ) + cof[3] * inputImage.at<uchar>((int)sampleRow + 1, (int)sampleCol  + 1);pixel_adress2[j] > 256 ? 256 : pixel_adress2[j];//防止像素大小超出范围pixel_adress2[j] < 0 ? 0 : pixel_adress2[j];}}}imwrite("output.jpg", outputImage);imshow("output", outputImage);}


0 0