標籤:電腦視覺 視頻流 直線圓檢測
main.cpp
#include<stdio.h>#include <iostream>#include <vector>#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include<string> #include <sstream>#include "linefinder.h"#include<time.h>#include <opencv2\opencv.hpp> using namespace cv;using namespace std;int main(){stringstream ss; string str; stringstream sss; string strs; clock_t start,finish; double totaltime; start=clock();for(int i=1;i<=80;i++) { str="C:\\Users\\hsn\\Desktop\\直線檢測\\直線檢測\\作業2\\";//選擇80張圖片 ss.clear(); ss<<str; ss<<i; ss<<".jpg"; ss>>str; Mat image=imread(str,1); //讀入圖片if (!image.data)return 0; Mat img=image(Rect(0.4*image.cols,0.58*image.rows,0.4*image.cols,0.3*image.rows));//選擇感興趣的地區//canny變換Mat contours;Canny(img,contours,80,100);Mat contoursInv;threshold(contours,contoursInv,128,255,THRESH_BINARY_INV);LineFinder ld;//LineFinder類型的一個變數,調用標頭檔函數// 設定Hough機率參數ld.setLineLengthAndGap(60,40);ld.setMinVote(30);//檢測直線vector<Vec4i> li= ld.findLines(contours);//畫直線ld.drawDetectedLines(img);/////////檢測圓Mat imgGry;cvtColor(image,imgGry,CV_BGR2GRAY);GaussianBlur(imgGry,imgGry,Size(5,5),1.5);//高斯平滑vector<Vec3f> circles;HoughCircles(imgGry, circles, CV_HOUGH_GRADIENT, 2, // 累加器解析度 (映像大小的一半) 150, // 兩圓之間最小距離200, // Canny變換高閾值100, // 最小支援數25, 50); // 最小和最大半徑cout << "Circles: " << circles.size() << endl;//輸出圓的個數// /////////////////畫圓vector<Vec3f>::const_iterator itc= circles.begin();while (itc!=circles.end()) {circle(image, Point((*itc)[0], (*itc)[1]), // 圓心(*itc)[2], // 半徑Scalar(255), // 顏色 2); // 寬度++itc;}//////儲存圖片strs="C:\\Users\\hsn\\Desktop\\直線檢測\\直線檢測\\處理後\\";//選擇80張圖片 sss.clear(); sss<<strs; sss<<i; sss<<".jpg"; sss>>strs; imwrite(strs,image);//寫入}finish=clock(); totaltime=(double)(finish-start)/CLOCKS_PER_SEC; cout<<"\n平均每幀已耗用時間為"<<totaltime/80<<"秒!"<<endl;////////////////////將圖片合成視頻int num = 1; CvSize size = cvSize(1024,960); //視訊框架格式的大小 double fps = 10;////每秒鐘的幀率 CvVideoWriter *writer = cvCreateVideoWriter("C:\\Users\\hsn\\Desktop\\直線檢測\\直線檢測\\路線路牌檢測.avi",-1,fps,size); //建立視頻檔案 char cname[100]; sprintf(cname,"C:\\Users\\hsn\\Desktop\\直線檢測\\直線檢測\\處理後\\%d.jpg",num); //載入圖片的檔案夾,圖片的名稱編號是1開始1,2,3,4,5.。。。 IplImage *src = cvLoadImage(cname); if (!src) { return 0; } IplImage *src_resize = cvCreateImage(size,8,3); //建立視頻檔案格式大小的圖片 cvNamedWindow("avi"); while (src) { cvShowImage("avi",src_resize); cvWaitKey(1); cvResize(src,src_resize); //<span style="white-space:pre"> </span>//將讀取的圖片設定為視頻格式大小相同 cvWriteFrame(writer,src_resize); //儲存圖片為視頻流格式 cvReleaseImage(&src);// <span style="white-space:pre"> </span> //釋放空間 num++; sprintf(cname,"C:\\Users\\hsn\\Desktop\\直線檢測\\直線檢測\\處理後\\%d.jpg",num); src = cvLoadImage(cname); //迴圈讀取資料 } cvReleaseVideoWriter(&writer); cvReleaseImage(&src_resize); waitKey();return 0;}
LineFinder.h
#if !defined LINEF#define LINEF#include<cmath>#include <opencv2/core/core.hpp>#include <opencv2/imgproc/imgproc.hpp>#define PI 3.1415926using namespace cv;using namespace std;class LineFinder {private:// 原始映像Mat img;vector<Vec4i> lines;//包含結束點的檢測直線// 累加器解析度double deltaRho;double deltaTheta;// 直線得到支援的最小個數int minVote;// 直線的最短長度double minLength;// 最大允許誤差double maxGap;public:// 預設累加器解析度是PI/180// 沒有最大允許誤差,沒有最小長度LineFinder() : deltaRho(1), deltaTheta(PI/180), minVote(10), minLength(0.), maxGap(0.) {}// 設定累加器解析度void setAccResolution(double dRho, double dTheta) {deltaRho= dRho;deltaTheta= dTheta;}// 設定最小支援數void setMinVote(int minv) {minVote= minv;}// 設定最大允許誤差和最小直線長度void setLineLengthAndGap(double length, double gap) {minLength= length;maxGap= gap;}// 應用機率霍夫變換vector<Vec4i> findLines(Mat& binary) {lines.clear();HoughLinesP(binary,lines,deltaRho,deltaTheta,minVote, minLength, maxGap);return lines;}//在映像上畫找到的直線void drawDetectedLines(Mat &image, Scalar color=Scalar(255,0,0)) {// 畫直線vector<Vec4i>::const_iterator it2= lines.begin();while (it2!=lines.end()) {Point pt1((*it2)[0],(*it2)[1]); Point pt2((*it2)[2],(*it2)[3]);double slope = fabs(double((*it2)[1]-(*it2)[3])/((*it2)[0]-(*it2)[2]));//計算斜率if((slope>0.53)&&(slope<2))//如果斜率滿足範圍進行畫線{line( image, pt1, pt2, color,3,8,0);}++it2;}}};#endif
opencv2實現路線路牌檢測_電腦視覺大作業2終版