OpenCV實現圖像的灰度化->二值化->Canny邊緣檢測以及對比度(Contrast)和亮度(Brightness)值調整ios
圖像灰度化:簡單的來講就是使R,G,B value在閾值[0,255]間取得相同的值,總共有256個等級,黑白兩種顏色其實能夠當作是灰度化處於兩個極端時的情形,中間254個等級分別表明灰度化的程度(淺深)。c++
圖像二值化:簡單的來講就是將圖像上的像素點的灰度值設置爲(0,0,0)(黑色)或(255,255,255)(白色),使圖像只呈現出明顯的黑白效果。算法
Canny算子:其目的是找到一個最優的邊緣檢測算法,使其知足三個主要的標準:編程
1.低錯誤率:標識出盡量多的邊緣,同時儘可能減小噪聲產生的影響;函數
2.高定位:標識出的邊緣應與圖像的實際邊緣儘量接近;學習
3.最小響應:圖像中的邊緣只能標識一次,而且可能存在的圖像噪聲不該標識爲邊緣。ui
Canny邊緣檢測步驟:濾波->計算梯度幅值和方向->非極大值抑制(排除非邊緣像素,保留候選邊緣) (每一個步驟的具體原理可參考OpenCV3編程入門這本書,百度一下pdf版應該就能找到,建議最好買一本,聲明一下:絕對不是打廣告 (●'◡'●))。spa
亮度和對比度調整:首先應瞭解點操做(點算子)這個概念:根據輸入像素值(有時可加上某些全局信息或參數),來計算輸出像素的值。這類算子包括亮度和對比度調整,顏色校訂(colorcorrection)和變換(transformations)。兩種最經常使用的點操做知足下式:3d
g(i,j)=a*f(i,j)+b 指針
(a控制對比度,b控制亮度,f(i,j)爲源圖像像素,g(i,j)爲輸出圖像像素)
本Demo中也是使用三個for循環來執行圖像亮度與對比度的調整。廢話很少說,代碼不會騙人,(●'◡'●)。
工程代碼以下:
//-----------------------------------【頭文件包含部分】-----------------------------------------
// 描述:包含程序所依賴的頭文件
//----------------------------------------------------------------------------------------------
#include <cv.h>
#include <highgui.h>
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
//-----------------------------------【命名空間聲明部分】--------------------------------------
// 描述:包含程序所使用的命名空間
//---------------------------------------------------------------------------------------------
using namespace std;
using namespace cv;
//-----------------------------------【全局變量聲明部分】--------------------------------------
// 描述:全局變量聲明
//---------------------------------------------------------------------------------------------
int g_nContrastValue; //對比度值
int g_nBrightValue; //亮度值
int Thresh = 50;
//-----------------------------------【全局函數聲明部分】--------------------------------------
// 描述:全局函數聲明
//---------------------------------------------------------------------------------------------
static void ContrastAndBright(int);
void ShowHelpText();
//-----------------------------------【聲明圖像IplImage指針】----------------------------------
//描述:聲明圖像IplImage指針
//---------------------------------------------------------------------------------------------
IplImage* g_pSrcImg = NULL;
IplImage* g_pGrayImage = NULL;
IplImage* g_pCannyImg = NULL;
IplImage *g_pBinaryImage = NULL;
IplImage *g_pDstImage = NULL;
//滑動條響應函數
void onTrackerSlid(int thresh)
{
cvCanny(g_pGrayImage, g_pCannyImg, (float)thresh, (float)thresh * 3, 3);
cvShowImage("Canny Image", g_pCannyImg);
}
//-----------------------------【on_trackbar( )函數】------------------------------------
// 描述:圖像二值化閾值回調函數
//-----------------------------------------------------------------------------------------------
void on_trackbar(int pos)
{
// 轉爲二值圖
cvThreshold(g_pGrayImage, g_pBinaryImage, pos, 255, CV_THRESH_BINARY);
// 顯示二值圖
cvShowImage("Binary Image", g_pBinaryImage);
}
//-----------------------------------【main( )函數】--------------------------------------------
// 描述:控制檯應用程序的入口函數,程序從這裏開始執行
//-----------------------------------------------------------------------------------------------
int main(int argc, char** argv)
{
system("color 5F");
ShowHelpText();
if (argc != 2)
argv[1] = "1.jpg";
//設定對比度和亮度的初值
g_nContrastValue = 80;
g_nBrightValue = 80;
//載入圖像,強制轉化爲Gray
if ((g_pSrcImg = cvLoadImage(argv[1], 1)) != 0)
{
cout << "Press ESC to Quit" << endl;
//將顏色空間由RGB轉化爲Gray
g_pGrayImage = cvCreateImage(cvGetSize(g_pSrcImg), 8, 1);
cvCvtColor(g_pSrcImg, g_pGrayImage, CV_RGB2GRAY);
// 建立二值圖
g_pBinaryImage = cvCreateImage(cvGetSize(g_pGrayImage), IPL_DEPTH_8U, 1);
//canny邊緣檢測
g_pCannyImg = cvCreateImage(cvGetSize(g_pGrayImage), IPL_DEPTH_8U, 1);
cvNamedWindow("ContrastandBrightnessWnd", CV_WINDOW_AUTOSIZE);
//建立軌跡條
cvCreateTrackbar("Contrast:", "ContrastandBrightnessWnd", &g_nContrastValue, 300, ContrastAndBright);
cvCreateTrackbar("Brightness:", "ContrastandBrightnessWnd", &g_nBrightValue, 200, ContrastAndBright);
//調用回調函數
ContrastAndBright(g_nContrastValue);
ContrastAndBright(g_nBrightValue);
//建立窗口
cvNamedWindow("Source Image", CV_WINDOW_AUTOSIZE);
cvNamedWindow("Gray Image", CV_WINDOW_AUTOSIZE);
cvNamedWindow("Canny Image", CV_WINDOW_AUTOSIZE);
cvNamedWindow("Binary Image", CV_WINDOW_AUTOSIZE);
// 滑動條
int nThreshold = 0;
cvCreateTrackbar("Threshold:", "Binary Image", &nThreshold, 254, on_trackbar);
on_trackbar(1);
//添加滑動條來調節邊緣檢測的閾值
onTrackerSlid(Thresh);
cvShowImage("Gray Image", g_pCannyImg);
cvCreateTrackbar("Threshold", "Canny Image", &Thresh, 300, onTrackerSlid);
//顯示圖像
cvShowImage("Source Image", g_pSrcImg);
cvShowImage("Gray Image", g_pGrayImage);
//保存圖像
cvSaveImage("Gray_Image.jpg", g_pGrayImage);
cvSaveImage("Canny_Image.jpg", g_pCannyImg);
cvSaveImage("Binary Image.jpg", g_pBinaryImage);
//等待按"ESC"鍵退出
while (1)
if (cvWaitKey(100) == 27)
break;
//銷燬窗口
cvWaitKey(0);
cvDestroyWindow("Source Image");
cvDestroyWindow("Canny Image");
cvDestroyWindow("Gray Image");
cvDestroyWindow("Binary Image");
//釋放圖像
cvReleaseImage(&g_pGrayImage);
cvReleaseImage(&g_pCannyImg);
cvReleaseImage(&g_pSrcImg);
cvReleaseImage(&g_pBinaryImage);
return 0;
}
return -1;
}
//-----------------------------【ContrastAndBright( )函數】------------------------------------
// 描述:改變圖像對比度和亮度值的回調函數
//---------------------------------------------------------------------------------------------
static void ContrastAndBright(int)
{
// 三個for循環,執行運算 dstImg(i,j) = a*srcImg(i,j) + b
Mat srcImg, dstImg;
srcImg = imread("lena.jpg");
if (!srcImg.data)
{
printf("讀取srcImg圖片錯誤~! \n");
return ;
}
dstImg = Mat::zeros(srcImg.size(), srcImg.type());
for (int y = 0; y < srcImg.rows; y++)
{
for (int x = 0; x <srcImg.cols; x++)
{
for (int c = 0; c < 3; c++)
{
dstImg.at<Vec3b>(y, x)[c] = saturate_cast<uchar>((g_nContrastValue*0.01)*(srcImg.at<Vec3b>(y, x)[c]) + g_nBrightValue);
}
}
}
// 顯示圖像
imshow("ContrastandBrightnessWnd", dstImg);
}
//-----------------------------------【ShowHelpText( )函數】----------------------------------
// 描述:輸出一些幫助信息
//----------------------------------------------------------------------------------------------
void ShowHelpText()
{
printf("\n\n\t\t\t 運行平臺爲win32 VS2013\n");
printf("\n\n\t\t\t OpenCV一個值得你學習的強大視覺庫\n");
printf("\n\n\t\t\t 當前使用的OpenCV版本爲:" CV_VERSION);
printf("\n\n ------------------------------------------------------------------------------------------------------------------\n");
}
程序運行結果
做者目前仍是個小菜鳥,若有錯誤,請指出來,相互交流一下,(●'◡'●)。