1. 程式人生 > >【數字影象處理】灰度變換函式(對數變換、反對數變換、冪次變換)

【數字影象處理】灰度變換函式(對數變換、反對數變換、冪次變換)

// 對比度增強.cpp : 定義控制檯應用程式的入口點。
//

#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <math.h>
#include <iostream>

using namespace cv;
using namespace std;

//歸一化
//data				進行處理的畫素集合
//grayscale			目標灰度級
//rows cols type	目標影象的行,列,以及型別
Mat Normalize(vector<double> data, int grayscale, int rows, int cols, int type)
{
	double max = 0.0;
	double min = 0.0;
	for(int i = 0;i < data.size();i++)
	{
		if(data[i] > max)
			max = data[i];
		if(data[i] < min)
			min = data[i];
	}
	Mat dst;
	dst.create(rows, cols, type);
	int index = 0;
	for(int r = 0;r < dst.rows;r++)
	{
		uchar* dstRowData = dst.ptr<uchar>(r);
		for(int c = 0;c < dst.cols;c++)
		{
			dstRowData[c] = (uchar)(grayscale * ((data[index++] - min) * 1.0 / (max - min)));
		}
	}
	return dst;
}

//對數變換
Mat LogTransform(Mat src, double parameter)
{
	vector<double> value;
	for(int r = 0;r < src.rows;r++)
	{
		uchar* rowData = src.ptr<uchar>(r);
		for(int c = 0;c < src.cols;c++)
		{
			//對數變換公式s = c * log(1 + v * r) / log(v + 1)
			//其中r為輸入影象畫素,c為常數,v + 1為對數底
			value.push_back(log(1 + parameter * rowData[c]) / log(parameter + 1));
		}
	}
	//計算得出的s經過對比拉昇(將畫素值歸一化到0-255)得到最終的影象
	return Normalize(value, 255, src.rows, src.cols, src.type());
}

//反對數變換
Mat NegativeLogTransform(Mat src, double parameter)
{
	vector<double> value;
	for(int r = 0;r < src.rows;r++)
	{
		uchar* srcRowData = src.ptr<uchar>(r);
		for(int c = 0;c < src.cols;c++)
		{
			//反對數變換公式為s = ((v + 1) ^ r - 1) / v
			value.push_back((pow(parameter + 1, srcRowData[c]) - 1) / parameter);
		}
	}
	//計算得出的s經過對比拉昇(將畫素值歸一化到0-255)得到最終的影象
	return Normalize(value, 255, src.rows, src.cols, src.type());
}

//冪次變換
Mat PowerTranseform(Mat src, double gamma, int parameter)
{
	Mat dst;
	dst.create(src.size(), src.type());
	vector<double> value;
	for(int r = 0;r < src.rows;r++)
	{
		uchar* srcRowData = src.ptr<uchar>(r);
		for(int c = 0;c < src.cols;c++)
		{
			//冪次變換的公式為 s = c * r ^ v	r為輸入影象畫素
			value.push_back(parameter * pow((double)srcRowData[c], gamma));
		}
	}
	return Normalize(value, 255, src.rows, src.cols, src.type());
}

int _tmain(int argc, _TCHAR* argv[])
{
	Mat srcImg = imread("E:\\學習之路\\OpenCV 練習程式\\01.jpg",0);
	if(srcImg.data == NULL)
	{
		cout << "影象開啟失敗" << endl;
	}
	imshow("原圖",srcImg);
	//Mat dstImg = LogTransform(srcImg,0.2);
	Mat dstImg;
	//dstImg = NegativeLogTransform(srcImg, 3);
	dstImg = PowerTranseform(srcImg, 0.4, 1);
	imshow("變換後",dstImg);
	waitKey(0);
	return 0;
}