OpenCV入門學習第一篇
阿新 • • 發佈:2019-02-02
接觸到影象處理,不免要用到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、彩色影象三通道影象提取
函式原型:
- void cvSplit(const CvArr* src,CvArr *dst0,CvArr *dst1, CvArr *dst2, CvArr *dst3);
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、.