1. 程式人生 > >OpenCV入門學習第一篇

OpenCV入門學習第一篇

      接觸到影象處理,不免要用到OpenCV,豐富的影象處理函式,不僅在追求高效能(基於C實現)上而且開源庫更是方便開發者不斷擴充套件openCV庫。是計算機視覺研究方向的必要開發工具。由於剛剛接觸OpenCV,本文主要是是對於OpenCV一些簡單例項的測試與實現。

  1、OpenCV的安裝配置

    對於OpenCV的安裝網上很多帖子,這裡就不用過多介紹了,做幾點說明。(參考:http://blog.csdn.net/poem_qianmo/article/details/19809337  和     http://blog.csdn.net/morewindows/article/details/8225783)

I:注意VS版本與OpenCV的版本,有些OpenCV只包含VC14,就只能和VS2015配合使用.

II:VS新增專案注意選擇win32還是X64,本人系統是64位的,執行Win32會報錯

III:包含庫檔案的時候注意是Debug還是Release,debug版的lib帶d的.

IV:配置環境變數後注意重啟電腦,重啟,之前以為不用重啟,但是無法是配置生效,所以還是乖乖重啟吧。

   2、第一個OpenCV例子----顯示一張圖片

//第一個例子:顯示影象
void showImage(){
	//IplImage 結構體
	IplImage *img = cvLoadImage("1234.jpg");//lena.tif
	if (img == NULL){
		cout << "Load File Failed.\n";
		return;
	}

	//建立一個視窗,如果值設定為0.使用者可以調整視窗的大小。 CV_WINDOW_AUTOSIZE = 1,視窗自適應圖片大小,無法調整視窗
	cvNamedWindow("Origin Image", CV_WINDOW_AUTOSIZE);
	cvShowImage("Origin Image", img);
	//設定時間,單位為ms.如果函式引數為0,則一直等待使用者按鍵
	cvWaitKey(0);
	cvReleaseImage(&img);
	//關閉視窗,釋放該視窗分配的所有記憶體
	cvDestroyWindow("Origin Image");
}


結果圖:帥氣的米勒


3、利用OpenCV播放視訊

// OpenCVvideo.cpp : 定義控制檯應用程式的入口點。
//

#include "stdafx.h"
#include "cv.h"
#include "highgui.h"

int  main(int argc, char* argv[]) {
	const char* inputVideo = "my.mp4";
	//cvCaptureFromAVI(inputVideo);   
	//openCV 有如下定義:#define cvCaptureFromAVI cvCaptureFromFile
	//					 #define cvCaptureFromFile cvCreateFileCapture		
	//cvCreateFileCapture(inputVideo) cvCaptureFromAVI(inputVideo);
	CvCapture* capture = cvCreateFileCapture(inputVideo); 
	int i = 0;
	IplImage* img = 0;
	char image_name[25];
	cvNamedWindow("video");

	//計算每秒幀數
	double fps = cvGetCaptureProperty(capture,CV_CAP_PROP_FPS);
	printf("fps=%d\n", (int)fps);
	//讀取和顯示  
	while (1)
	{
		//獲取一幀圖片 
		//cvQueryFrame()函式實際上是cvGrabFrame()和 cvRetrieveFrame()的一個組合
		img = cvQueryFrame(capture);  
		if (img == NULL)
			break;
		//顯示  
		cvShowImage("video", img); 
		char key = cvWaitKey(20);
		//將每一幀儲存到images資料夾下
		sprintf(image_name, "%s%d%s", "images\\image", ++i, ".jpg");//儲存的圖片名  
		cvSaveImage(image_name, img);  
	}

	cvReleaseCapture(&capture);
	cvDestroyWindow("video");
	return 0;
}


輸出:fps=29   

這是儲存的幀,在images資料夾下

4、OpenCV設定ROI區域,ROI=region of interesting,就是設定感興趣的區域,如果對影象設定了ROI區域,則接下來相應的影象操作只會作用於該區域,直到釋放該區域。
程式碼是將一部分割槽域設定為白色,如果不設定ROI區域,則整幅影象都變成白色。所以,在影象處理中這是經常用到的方法,我們只關注於我們感興趣的影象區域。

程式碼如下:

void testROI(){
	IplImage *image = cvLoadImage("lenaRGB.tif");
	cout << "Width:" << image->width<<endl;
	cout << "Height:" << image->height<<endl;
	cout << "Step:" << image->widthStep<<endl;
	//設定ROI
	cvSetImageROI(image, cvRect(0, 100, 100, 100));
	//ROI 區域加上一個標量
	cvAddS(image, cvScalar(255,255,255), image);
	//釋放ROI,否則只會顯示ROI 區域
	cvResetImageROI(image);

	//show image
	cvNamedWindow("ROI", 1);
	cvShowImage("ROI", image);
	cvWaitKey();

	cvReleaseImage(&image);
	cvDestroyWindow("ROI");
}


4、彩色影象三通道影象提取

函式原型:

  1. void cvSplit(const CvArr* src,CvArr *dst0,CvArr *dst1, CvArr *dst2, CvArr *dst3);  
注意:該函式分離是按BGR順序分離的。 程式碼如下:
void imageSplit(){
	IplImage *image = cvLoadImage("RGB.tif");
	IplImage *imgR = NULL, *imgG = NULL, *imgB = NULL , *imgMerge=NULL;
	//根據影象深度大小和影象深度,建立單通道影象
	imgR = cvCreateImage(cvGetSize(image), image->depth, 1);
	imgG = cvCreateImage(cvGetSize(image), image->depth, 1);
	imgB = cvCreateImage(cvGetSize(image), image->depth, 1);
	//建立一個預合成的三通道影象
	imgMerge = cvCreateImage(cvGetSize(image), image->depth, 3);

	//分離出來的順序是逆序的    cvSplit(pImg,bImg,gImg,rImg,0)
	cvSplit(image, imgB, imgG, imgR, NULL);
	cvNamedWindow("Origin", CV_WINDOW_AUTOSIZE);
	cvNamedWindow("Red", CV_WINDOW_AUTOSIZE);
	cvNamedWindow("Green", CV_WINDOW_AUTOSIZE);
	cvNamedWindow("Blue", CV_WINDOW_AUTOSIZE);
	cvShowImage("Origin", image);
	cvShowImage("Red", imgR);
	cvShowImage("Green", imgG);
	cvShowImage("Blue", imgB);


	//合併順序也是相反的
	cvMerge(imgB, imgG, imgR, NULL, imgMerge);
	cvNamedWindow("Merge", CV_WINDOW_AUTOSIZE);
	cvShowImage("Merge", imgMerge);
	cvWaitKey();

	cvReleaseImage(&imgR);
	cvReleaseImage(&imgG);
	cvReleaseImage(&imgB);
	cvReleaseImage(&image);
	cvReleaseImage(&image);
	cvReleaseImage(&imgMerge);

	cvDestroyWindow("Origin");
	cvDestroyWindow("Red");
	cvDestroyWindow("Green");
	cvDestroyWindow("Blue");
	cvDestroyWindow("Merge");

}
結果如下:

5、影象縮放

影象縮放-即插值函式的呼叫,OpenCV提供了幾種插值方法。 程式碼:
void imageScale(){
	IplImage *srcImage = cvLoadImage("lena.tif");
	IplImage *dstImage = NULL; 
	double fScale = 0.5;
	int deep = srcImage->depth;
	int channel = srcImage->nChannels;
	cout << "Deep:" << deep << endl << "Channel:" << channel << endl;
	cout << "Width:" << srcImage->width << "  Height:" << srcImage->height << endl;
	
	CvSize size;
	size.width = srcImage->width * fScale;
	size.height = srcImage->height * fScale;
	dstImage = cvCreateImage(size, deep, channel);
	// CV_INTER_NN -最鄰近插值     CV_INTER_LINEAR  -雙線性插值     CV_INTER_AREA  --使用象素關係重取樣
	// CV_INTER_CUBIC  -立方插值
	cvResize(srcImage, dstImage, CV_INTER_CUBIC);

	cvNamedWindow("Source", CV_WINDOW_AUTOSIZE);
	cvShowImage("Source", srcImage);
	cvNamedWindow("Scale", CV_WINDOW_AUTOSIZE);
	cvShowImage("Scale", dstImage);
	cvWaitKey();
	cvSaveImage("scaleImageCUBIC.tif", dstImage);
	

	cvReleaseImage(&srcImage);
	cvReleaseImage(&dstImage);
	cvDestroyWindow("Source");
	cvDestroyWindow("Scale");
}

6、影象平滑

函式原型:void cvSmooth( const CvArr* src, CvArr* dst,int smoothtype=CV_GAUSSIAN,int param1, int param2, double param3, double param4 ); smoothtype平滑方法:
CV_BLUR_NO_SCALE(簡單不帶尺度變換的模糊) - -對每個象素的 param1×param2 領域求和。如果鄰域大小是變化的,可以事先利用函式 cvIntegral 計算積分影象。
CV_BLUR (simple blur)- -對每個象素param1×param2鄰域求和並做尺度變換 1/(param1×param2)。
CV_GAUSSIAN(gaussian blur) - -對影象進行核大小為 param1×param2 的高斯卷積。
CV_MEDIAN(median blur) - -對影象進行核大小為param1×param1 的中值濾波 (鄰域是方的)。
CV_BILATERAL(雙向濾波) - -應用雙向 3x3 濾波,彩色 sigma=param1,空間 sigma=param2.。 以下例項是對帶有椒鹽噪聲的影象進行處理:高斯濾波和中值濾波
//利用高斯濾波器平滑影象
void smoothImage(){
	//IplImage 結構體
	IplImage *img = cvLoadImage("lenaNoise.tif");
	cvNamedWindow("OriginImage", 0);
	cvShowImage("OriginImage", img);
	//3*3的高斯濾波器
	IplImage *out_imageG = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 3);
	cvNamedWindow("GauImage", 0);
	//3*3的中值濾波器
	IplImage *out_imageM = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 3);
	cvNamedWindow("MedImage", 0);


	cvSmooth(img, out_imageG, CV_GAUSSIAN, 3, 3);
	cvShowImage("GauImage",out_imageG);

	cvSmooth(img, out_imageM, CV_MEDIAN, 3, 3);
	cvShowImage("MedImage", out_imageM);

	cvWaitKey(0);

	cvReleaseImage(&img);
	cvReleaseImage(&out_imageG);
	cvReleaseImage(&out_imageM);
	cvDestroyWindow("OriginImage");
	cvDestroyWindow("GauImage");
	cvDestroyWindow("MedImage");
}
結果如下:如預期一樣,中值濾波對於椒鹽噪聲的處理效果比較好

7、.