C++ opencv圖像處理實現灰度變換示例

灰度變換概念

在圖像預處理中,圖像的灰度變換是圖像增強的重要手段,灰度變換可以使圖像對比度擴展,圖像清晰,特征明顯,灰度變換主要利用點運算來修正像素灰度,由輸入像素點的灰度值確定相應輸出點的灰度值,是一種基於圖像變換的操作。

灰度變換的作用

1.改善圖像是質量,顯示更多的細節,提高圖像的對比度

2.有選擇的突出圖像感興趣的特征或者抑制圖像中不需要的特征

3.可以有效的改變圖像的直方圖的分佈,使像素的分佈更加均勻

灰度變換的方法

1.線性灰度變換

2.非線性灰度變換(對數變換,冪律變換(伽馬變換))

灰度化

灰度的概念

在數字圖像中,像素是基本的表示單位,各個像素的亮安程度用灰度值來標識,隻含亮度信息,不含色彩信息的圖像稱為灰度圖像,對於單色圖像,它的每個像素的灰度值用【0,255】區間的整數表示,即圖像分為256個灰度等級,對於彩色圖像,他的每個像素由R,G,B三個單色調配而成,如果每個像素的R,G,B完全相同,也就是R=G=B=D,該圖像就是灰度圖像,其中D被稱為各個像素的灰度值。

對彩色圖進行灰度化

1.加權平均值法

D=0.299R+0.587G+0.114*B

代碼如下:

#include<iostream>
#include<opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
	Mat img, img2;
	img = imread("貓1.jpg");
	imshow("原圖", img);
	img2.create(img.size(), 0);
	for (int i = 0; i < img.rows; i++)
	{
		for (int j = 0; j < img.cols; j++)
		{
			img2.at<uchar>(i, j) = saturate_cast<uchar>(0.114*img.at<Vec3b>(i, j)[0] + 0.587*img.at<Vec3b>(i, j)[1] + 0.299*img.at<Vec3b>(i, j)[2]);
		}
	}
	imshow("經驗公式", img2);
	waitKey(0);
}

效果如下:

2.取最大值

代碼如下:

int main()
{
	Mat img, img2;
	img = imread("貓1.jpg");
	imshow("原圖", img);
	img2.create(img.size(), 0);
	for (int i = 0; i < img.rows; i++)
	{
		for (int j = 0; j < img.cols; j++)
		{
			int max = img.at<Vec3b>(i, j)[0];
			for (int x = 0; x < 3; x++)
			{
				if (max < img.at<Vec3b>(i, j)[x])
				{
					max = img.at<Vec3b>(i, j)[x];
				}
			}
			img2.at<uchar>(i, j) = saturate_cast<uchar>(max);
		}
	}
	imshow("最大值", img2);
	waitKey(0);
}

3.平均值

代碼如下:

int main()
{
	Mat img, img2;
	img = imread("貓1.jpg");
	imshow("原圖", img);
	img2.create(img.size(), 0);
	for (int i = 0; i < img.rows; i++)
	{
		for (int j = 0; j < img.cols; j++)
		{
			img2.at<uchar>(i, j) = saturate_cast<uchar>((img.at<Vec3b>(i, j)[0] + img.at<Vec3b>(i, j)[1] + img.at<Vec3b>(i, j)[2])/3);
		}
	}
	imshow("平均值", img2);
	waitKey(0);
}

灰度的線性變換

圖像的線性變換是圖像處理的基本運算,通常應用在調整圖像的畫面質量方面,如圖像對比度,亮度及反轉等操作。灰度的線性變換就是將圖像中所有點的灰度按照線性灰度變換函數進行變換。

1.線性變換

y=kx+b;

代碼如下:

int main()
{
	Mat img1, img2;
	img1 = imread("貓1.jpg", 1);
	imshow("原圖", img1);
	img2 = Mat::zeros(img1.size(), 0);
	for (int i = 0; i < img1.rows; i++)
	{
		for (int j = 0; j < img1.cols; j++)
		{
			for (int s = 0; s < 3; s++)
			{
				img2.at<uchar>(i, j) = saturate_cast<uchar>(1.1*img1.at<Vec3b>(i, j)[s] + 20);
			}
		}
	}
	imshow("線性", img2);
	waitKey(0);
}

效果如下:

2.分段線性變換

請添加圖片描述

代碼如下:

int main()
{
	Mat img1, img2;
	img1 = imread("貓1.jpg", 0);
	imshow("原圖", img1);
	img2 = Mat::zeros(img1.size(), 0);
	for (int i = 0; i < img1.rows; i++)
	{
		for (int j = 0; j < img1.cols; j++)
		{
			uchar temp = img1.at<uchar>(i, j);
			if (temp <=70)
			{
				img2.at<uchar>(i, j) = saturate_cast<uchar>(0.5*temp + 20);
			}
			else if (temp > 70 && temp <= 150)
			{
				img2.at<uchar>(i, j) = saturate_cast<uchar>(1.2*temp + 100);
			}
			else if (temp > 150 && temp <= 255)
			{
				img2.at<uchar>(i, j) = saturate_cast<uchar>(0.9*temp + 55);
			}
		}
	}
	imshow("分段線性", img2);
	waitKey(0);
}

效果如下:

灰度的非線性變換

對數變換和分對數變換都屬於非線性變換

1.對數變換

對數變換能增強圖像暗部的細節

代碼如下:

int main()
{
	double c = 1.2;
	Mat img1, img2, img3;
	img1 = imread("貓1.jpg",0);
	img3 = Mat::ones(img1.size(), CV_32FC3);
	add(img1, Scalar(1.0), img1);
	img1.convertTo(img1, CV_32F);
	log(img1, img3);
	img3 = c*img3;
	normalize(img3, img3, 0, 255, NORM_MINMAX);//歸一化到0-255 NORM_MINMAX 線性歸一化
	convertScaleAbs(img3, img3);//轉換成8bit通道顯示
	imshow("對數變換", img3);
	waitKey(0);
}

效果如下:

2.冪律變換

冪律變換也稱伽馬變換或指數變換,主要用於圖像的校正,對漂白的圖片或過黑的圖片進行修正,增強對比度

代碼如下:

int main()
{
	Mat img1, img2;
	img1 = imread("貓1.jpg",0);
	img2.create(img1.size(), img1.type());
	for (int i = 0; i < img1.rows; i++)
	{
		for (int j = 0; j < img1.cols; j++)
		{
			int gray = img1.at<uchar>(i, j);
			img2.at<uchar>(i, j) = saturate_cast<uchar>(pow(gray,0.5));
		}
	}
	normalize(img2, img2, 0, 255, NORM_MINMAX);
	imshow("冪律變換", img2);
	waitKey(0);
}

效果如下:

總結

以上就是本文的全部內容,本文簡單介紹瞭灰度化以及灰度變換的一些基礎知識,更多關於C++ opencv灰度變換的資料請關註LevelAH其它相關文章!

推薦閱讀: