cv1.0入门
来源:互联网 发布:开眼角疤痕知乎 编辑:程序博客网 时间:2024/06/06 12:59
作者 群号 C语言交流中心 240137450 微信 15013593099
环境
VS2010UltimTrial1.iso http://pan.baidu.com/s/1dEL85kl
VS2010UltimTrialCHS版注册码 YCFHQ-9DWCY-DKV88-T2TMH-G7BHP
opencv-2.4.9.exe http://pan.baidu.com/s/1kVaVwoR
图片地址: f:\img\
操作系统:
XP http://pan.baidu.com/s/1bY5SHS
SP3 http://pan.baidu.com/s/1bAPuGY
运行在虚拟机中 VM10.0.3 build-1895310 http://pan.baidu.com/s/1dEQsno1
VMKEY 5F29M-48312-8ZDF9-A8A5K-2AM0Z
1Y0W5-0W205-7Z8J0-C8C5M-9A6MF
读取文件
#include <opencv2\highgui\highgui.hpp>#include <iostream> using namespace cv;using namespace std; int main(int argc, const char** argv){ Mat img = imread("f:\\img\\lena.jpg"); if (img.empty()) { cout << "图像加载失败!" << endl; return -1; } //创建一个名字为MyWindow的窗口 namedWindow("MyWindow", CV_WINDOW_AUTOSIZE); //在MyWindow的窗中中显示存储在img中的图片 imshow("MyWindow", img); //等待直到有键按下 waitKey(0); //销毁MyWindow的窗口 destroyWindow("MyWindow"); return 0;}
sobel laplace canny
#include <opencv2\opencv.hpp>#include <iostream> using namespace cv;using namespace std; int main(int argc, char* argv[]){ Mat src = imread("f:\\img\\QQ.png"); Mat dst; //输入图像 //输出图像 //输入图像颜色通道数 //x方向阶数 //y方向阶数 Sobel(src,dst,src.depth(),1,1); imwrite("sobel.jpg",dst);imshow("sobel",dst);imshow("src",src); //输入图像 //输出图像 //输入图像颜色通道数 Laplacian(src,dst,src.depth()); imwrite("laplacian.jpg",dst);imshow("laplacian",dst); //输入图像 //输出图像 //彩色转灰度 cvtColor(src,src,CV_BGR2GRAY); //canny只处理灰度图 //输入图像 //输出图像 //低阈值 //高阈值,opencv建议是低阈值的3倍 //内部sobel滤波器大小 Canny(src,dst,50,150,3); imwrite("canny.jpg",dst); imshow("canny",dst); waitKey(); return 0;}
轮廓
#include <opencv2\opencv.hpp>#include <iostream>using namespace cv;using namespace std;int main(){ const char* inputImage = "f:\\img\\circle.jpg"; Mat img; int threshval =100; img = imread(inputImage,0); if (img.empty()) { cout << "Could not read input image file: " << inputImage << endl; return -1; } img = img >110; //namedWindow("Img", 1); imshow("Img", img); vector<vector<Point> > contours; vector<Vec4i>hierarchy; Mat dst = Mat::zeros(img.rows, img.cols, CV_8UC3); findContours(img, contours,hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE); if( !contours.empty() && !hierarchy.empty() ) { int idx = 0; for( ; idx >= 0; idx = hierarchy[idx][0] ) { Scalar color( (rand()&255), (rand()&255), (rand()&255) ); drawContours( dst, contours, idx, color, 1, 8, hierarchy ); } } //namedWindow("Connected Components", 1); imshow( "Connected Components", dst ); waitKey(0); return 0;}
findContours函数,这个函数的原型为:
void findContours(InputOutputArray image, OutputArrayOfArrayscontours, OutputArray hierar-
chy, int mode, int method, Point offset=Point())
参数说明
输入图像image必须为一个2值单通道图像
contours参数为检测的轮廓数组,每一个轮廓用一个point类型的vector表示
hiararchy参数和轮廓个数相同,每个轮廓contours[ i ]对应4个hierarchy元素hierarchy[ i ][0 ] ~hierarchy[ i ][ 3],分别表示后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号,如果没有对应项,该值设置为负数。
mode表示轮廓的检索模式
CV_RETR_EXTERNAL表示只检测外轮廓
CV_RETR_LIST检测的轮廓不建立等级关系
CV_RETR_CCOMP建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。
CV_RETR_TREE建立一个等级树结构的轮廓。具体参考contours.c这个demo
method为轮廓的近似办法
CV_CHAIN_APPROX_NONE存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))==1
CV_CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息
CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain近似算法
offset表示代表轮廓点的偏移量,可以设置为任意值。对ROI图像中找出的轮廓,并要在整个图像中进行分析时,这个参数还是很有用的。
findContours后会对输入的2值图像改变,所以如果不想改变该2值图像,需创建新mat来存放,findContours后的轮廓信息contours可能过于复杂不平滑,可以用approxPolyDP函数对该多边形曲线做适当近似
contourArea函数可以得到当前轮廓包含区域的大小,方便轮廓的筛选
hough找直线
hough变换
#include <opencv2\opencv.hpp>#include <iostream>using namespace cv;using namespace std;#include <math.h>#define PI 3.14159265358979int main(int argc, char *argv[]){ cv::Mat image = cv::imread("f:\\img\\line.png"); //resize(image,image,Size(image.rows/2, image.cols/2),0,0,CV_INTER_LINEAR); cv::Mat contours; cv::cvtColor(image, contours, cv::COLOR_BGR2GRAY); cv::bitwise_not(contours, contours); //cv::Canny(image, contours, 155, 350); std::vector<cv::Vec2f> lines; cv::HoughLines(contours, lines, 1, PI/180, 180); //cv::imshow("cany",contours ); std::vector<cv::Vec2f>::const_iterator it= lines.begin();Mat dst = Mat::zeros(image.rows, image.cols, CV_8UC3); while (it!=lines.end()) { float rho= (*it)[0]; // first element is distance rho float theta= (*it)[1]; // second element is angle theta if (theta < PI/4. || theta > 3.*PI/4.)// ~vertical line { // point of intersection of the line with first row cv::Point pt1(rho/cos(theta), 0); // point of intersection of the line with last row cv::Point pt2((rho - image.rows * sin(theta))/cos(theta), image.rows); // draw a white line cv::line( dst, pt1, pt2, cv::Scalar(255), 1); } else { // ~horizontal line // point of intersection of the // line with first column cv::Point pt1(0,rho/sin(theta)); // point of intersection of the line with last column cv::Point pt2(image.cols, (rho - image.cols * cos(theta))/sin(theta)); // draw a white line cv::line(dst, pt1, pt2, cv::Scalar(255), 1); } ++it; } cv::imshow("src", image);cv::imshow("dst", dst);waitKey(0); return 0;}
概率hough变换
#include <opencv2\opencv.hpp>#include <iostream>using namespace cv;using namespace std;#include <math.h>#define PI 3.14159265358979class LineFinder{private: cv::Mat img; // original image std::vector<cv::Vec4i> lines; double deltaRho; double deltaTheta; int minVote; double minLength; // min length for a line double maxGap; // max allowed gap along the linepublic: // Default accumulator resolution is 1 pixel by 1 degree // no gap, no mimimum length LineFinder() : deltaRho(1), deltaTheta(PI/180), minVote(10), minLength(0.), maxGap(0.) {} // Set the resolution of the accumulator void setAccResolution(double dRho, double dTheta) { deltaRho= dRho; deltaTheta= dTheta; } // Set the minimum number of votes void setMinVote(int minv) { minVote= minv; } // Set line length and gap void setLineLengthAndGap(double length, double gap) { minLength= length; maxGap= gap; } // Apply probabilistic Hough Transform std::vector<cv::Vec4i> findLines(cv::Mat& binary) { lines.clear(); cv::HoughLinesP(binary, lines, deltaRho, deltaTheta, minVote, minLength, maxGap); return lines; } // Draw the detected lines on an image void drawDetectedLines(cv::Mat &image, cv::Scalar color = cv::Scalar(255, 255, 255)) { // Draw the lines std::vector<cv::Vec4i>::const_iterator it2 = lines.begin(); while (it2 != lines.end()) { cv::Point pt1((*it2)[0],(*it2)[1]); cv::Point pt2((*it2)[2],(*it2)[3]); cv::line( image, pt1, pt2, color, 2); ++it2; } }};int main(int argc, char *argv[]){ cv::Mat image = cv::imread("f:\\img\\line.png"); cv::Mat contours; cv::cvtColor(image, contours, cv::COLOR_BGR2GRAY); cv::bitwise_not(contours, contours); //cv::Canny(image, contours, 155, 350); LineFinder finder; // Set probabilistic Hough parameters finder.setLineLengthAndGap(100, 20); finder.setMinVote(80); // Detect lines and draw them std::vector<cv::Vec4i> lines = finder.findLines(contours); finder.drawDetectedLines(image, cv::Scalar(0, 0, 255)); //cv::namedWindow("Detected Lines with HoughP"); cv::imshow("Detected Lines with HoughP",image);waitKey(0); }
找圆 hough
#include <opencv2/opencv.hpp>using namespace cv;using namespace std;const int kvalue = 15;//双边滤波邻域大小int main(){Mat src_color = imread("f:\\img\\c1.png");//读取原彩色图imshow("原图-彩色", src_color);//声明一个三通道图像,像素值全为0,用来将霍夫变换检测出的圆画在上面Mat dst(src_color.size(), src_color.type());dst = Scalar::all(0);Mat src_gray;//彩色图像转化成灰度图cvtColor(src_color, src_gray, COLOR_BGR2GRAY);imshow("原图-灰度", src_gray);imwrite("src_gray.png", src_gray);Mat bf;//对灰度图像进行双边滤波bilateralFilter(src_gray, bf, kvalue, kvalue*2, kvalue/2);imshow("灰度双边滤波处理", bf);imwrite("src_bf.png", bf);vector<Vec3f> circles;//声明一个向量,保存检测出的圆的圆心坐标和半径HoughCircles(bf, circles, CV_HOUGH_GRADIENT, 1.5, 20, 130, 38, 10, 50);//霍夫变换检测圆cout << "x=\ty=\tr=" << endl;for(size_t i = 0; i < circles.size(); i++)//把霍夫变换检测出的圆画出来{Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));int radius = cvRound(circles[i][2]);circle( dst, center, 0, Scalar(0, 255, 0), -1, 8, 0 );circle( dst, center, radius, Scalar(0, 0, 255), 1, 8, 0 );cout << cvRound(circles[i][0]) << "\t" << cvRound(circles[i][1]) << "\t" << cvRound(circles[i][2]) << endl;//在控制台输出圆心坐标和半径}imshow("特征提取", dst);imwrite("dst.png", dst);waitKey();}
膨胀腐蚀
膨胀就是大了一圈 腐蚀就是小了一圈
#include <opencv2/opencv.hpp>using namespace cv;using namespace std;int main(int argc, char *argv[]){Mat src, erode_dst, dilate_dst; src = imread("f:\\img\\erode.png"); if (!src.data) { cout<<"Read image failure."<<endl; return -1; } erode(src, erode_dst, cv::Mat());dilate(src, dilate_dst, cv::Mat());namedWindow("src"); namedWindow("erode");namedWindow("dilate");imshow("src",src);imshow("erode",erode_dst);imshow("dilate",dilate_dst); waitKey(0); return 0;}
开闭2
<span style="font-size:14px;">#include <opencv\\cv.h>#include <opencv\\highgui.h>#include <stdlib.h>#include <stdio.h>IplImage* src = 0;IplImage* dst = 0;IplConvKernel* element = 0;int element_shape = CV_SHAPE_RECT;//the address of variable which receives trackbar position update int max_iters = 10;int open_close_pos = 0;int erode_dilate_pos = 0;// callback function for open/close trackbarvoid OpenClose(int pos) { int n = open_close_pos - max_iters; int an = n > 0 ? n : -n; element = cvCreateStructuringElementEx( an*2+1, an*2+1, an, an, element_shape, 0 ); if( n < 0 ) { cvErode(src,dst,element,1); cvDilate(dst,dst,element,1); } else { cvDilate(src,dst,element,1); cvErode(dst,dst,element,1); } cvReleaseStructuringElement(&element); cvShowImage("Open/Close",dst);} // callback function for erode/dilate trackbarvoid ErodeDilate(int pos) { int n = erode_dilate_pos - max_iters; int an = n > 0 ? n : -n; element = cvCreateStructuringElementEx( an*2+1, an*2+1, an, an, element_shape, 0 ); if( n < 0 ) { cvErode(src,dst,element,1); } else { cvDilate(src,dst,element,1); } cvReleaseStructuringElement(&element); cvShowImage("Erode/Dilate",dst);} int main( int argc, char** argv ){ char* filename = "f:\\img\\oc.png"; if( (src = cvLoadImage(filename,1)) == 0 ) return -1; printf( "Hot keys: \n" "\tESC - quit the program\n" "\tr - use rectangle structuring element\n" "\te - use elliptic structuring element\n" "\tc - use cross-shaped structuring element\n" "\tENTER - loop through all the options\n" ); dst = cvCloneImage(src); //create windows for output images cvNamedWindow("Open/Close",1);cvNamedWindow("src",1);cvShowImage("src",src); cvNamedWindow("Erode/Dilate",1); open_close_pos = erode_dilate_pos = max_iters; cvCreateTrackbar("iterations", "Open/Close",&open_close_pos,max_iters*2+1,OpenClose); cvCreateTrackbar("iterations", "Erode/Dilate",&erode_dilate_pos,max_iters*2+1,ErodeDilate); for(;;) { int c; OpenClose(open_close_pos); ErodeDilate(erode_dilate_pos); c = cvWaitKey(0); if( (char)c == 27 ) break; if( (char)c == 'e' ) element_shape = CV_SHAPE_ELLIPSE; else if( (char)c == 'r' ) element_shape = CV_SHAPE_RECT; else if( (char)c == 'c' ) element_shape = CV_SHAPE_CROSS; else if( (char)c == '\n' ) element_shape = (element_shape + 1) % 3; } //release images cvReleaseImage(&src); cvReleaseImage(&dst); //destroy windows cvDestroyWindow("Open/Close"); cvDestroyWindow("Erode/Dilate"); return 0;}</span>
距离变换
#include "opencv\\cv.h"#include "opencv\\highgui.h"#include <stdio.h>char wndname[] = "Distance transform";char tbarname[] = "Threshold";int mask_size = CV_DIST_MASK_5;int build_voronoi = 0;int edge_thresh = 100;// The output and temporary imagesIplImage* dist = 0;IplImage* dist8u1 = 0;IplImage* dist8u2 = 0;IplImage* dist8u = 0;IplImage* dist32s = 0;IplImage* gray = 0;IplImage* edge = 0;IplImage* labels = 0;// threshold trackbar callbackvoid on_trackbar( int dummy ){ static const uchar colors[][3] = { {0,0,0}, {255,0,0}, {255,128,0}, {255,255,0}, {0,255,0}, {0,128,255}, {0,255,255}, {0,0,255}, {255,0,255} }; int msize = mask_size; cvThreshold( gray, edge, (float)edge_thresh, (float)edge_thresh, CV_THRESH_BINARY ); if( build_voronoi ) msize = CV_DIST_MASK_5; cvDistTransform( edge, dist, CV_DIST_L2, msize, NULL, build_voronoi ? labels : NULL ); if( !build_voronoi ) { // begin "painting" the distance transform result cvConvertScale( dist, dist, 5000.0, 0 ); cvPow( dist, dist, 0.5 ); cvConvertScale( dist, dist32s, 1.0, 0.5 ); cvAndS( dist32s, cvScalarAll(255), dist32s, 0 ); cvConvertScale( dist32s, dist8u1, 1, 0 ); cvConvertScale( dist32s, dist32s, -1, 0 ); cvAddS( dist32s, cvScalarAll(255), dist32s, 0 ); cvConvertScale( dist32s, dist8u2, 1, 0 ); cvMerge( dist8u1, dist8u2, dist8u2, 0, dist8u ); // end "painting" the distance transform result } else { int i, j; for( i = 0; i < labels->height; i++ ) { int* ll = (int*)(labels->imageData + i*labels->widthStep); float* dd = (float*)(dist->imageData + i*dist->widthStep); uchar* d = (uchar*)(dist8u->imageData + i*dist8u->widthStep); for( j = 0; j < labels->width; j++ ) { int idx = ll[j] == 0 || dd[j] == 0 ? 0 : (ll[j]-1)%8 + 1; int b = cvRound(colors[idx][0]); int g = cvRound(colors[idx][1]); int r = cvRound(colors[idx][2]); d[j*3] = (uchar)b; d[j*3+1] = (uchar)g; d[j*3+2] = (uchar)r; } } } cvShowImage( wndname, dist8u );}int main( int argc, char** argv ){ char* filename = "f:\\img\\pf.jpg"; if( (gray = cvLoadImage( filename, 0 )) == 0 ) return -1;cvNamedWindow( "src", 1 );cvShowImage( "src", gray ); printf( "Hot keys: \n" "\tESC - quit the program\n" "\t3 - use 3x3 mask\n" "\t5 - use 5x5 mask\n" "\t0 - use precise distance transform\n" "\tv - switch Voronoi diagram mode on/off\n" "\tENTER - loop through all the modes\n" ); dist = cvCreateImage( cvGetSize(gray), IPL_DEPTH_32F, 1 ); dist8u1 = cvCloneImage( gray ); dist8u2 = cvCloneImage( gray ); dist8u = cvCreateImage( cvGetSize(gray), IPL_DEPTH_8U, 3 ); dist32s = cvCreateImage( cvGetSize(gray), IPL_DEPTH_32S, 1 ); edge = cvCloneImage( gray ); labels = cvCreateImage( cvGetSize(gray), IPL_DEPTH_32S, 1 ); cvNamedWindow( wndname, 1 ); cvCreateTrackbar( tbarname, wndname, &edge_thresh, 255, on_trackbar ); for(;;) { int c; // Call to update the view on_trackbar(0); c = cvWaitKey(0); if( (char)c == 27 ) break; if( (char)c == '3' ) mask_size = CV_DIST_MASK_3; else if( (char)c == '5' ) mask_size = CV_DIST_MASK_5; else if( (char)c == '0' ) mask_size = CV_DIST_MASK_PRECISE; else if( (char)c == 'v' ) build_voronoi ^= 1; else if( (char)c == '\n' ) { if( build_voronoi ) { build_voronoi = 0; mask_size = CV_DIST_MASK_3; } else if( mask_size == CV_DIST_MASK_3 ) mask_size = CV_DIST_MASK_5; else if( mask_size == CV_DIST_MASK_5 ) mask_size = CV_DIST_MASK_PRECISE; else if( mask_size == CV_DIST_MASK_PRECISE ) build_voronoi = 1; } } cvReleaseImage( &gray ); cvReleaseImage( &edge ); cvReleaseImage( &dist ); cvReleaseImage( &dist8u ); cvReleaseImage( &dist8u1 ); cvReleaseImage( &dist8u2 ); cvReleaseImage( &dist32s ); cvReleaseImage( &labels ); cvDestroyWindow( wndname ); return 0;}
- cv1.0入门
- open cv1.0与2.0是否兼容?
- Python中OpenCV2. VS. CV1
- cv1.2图像去除噪声
- cv1.6hist直方图操作
- cv1.4 访问通道数据
- 亲身体验Oculus Rift CV1
- cv1.3计算物体旋转角
- Oculus CV1安装配置、账号登录以及Unity在Oculus CV1上的运行
- 为DK2应用程序迁移到Oculus CV1做好准备!
- cv1.1 找mark点以及分水岭算法
- cv1.8凸包检测以及形态学滤波
- CV1——二值图像分析之连通域
- Unity中Oculus Rift CV1的手柄按键测试记录
- cv1.7去背景以及人脸检测人脸识别
- 【UE4学习】10_Oculus CV1 小遥控器的输入(input)控制
- Oculus cv1安装教程以及在Unity环境手柄的开发
- Oculus Rift CV1 驱动安装教程(内含Oculus官方Demo)
- android fragment取消预加载
- Android Activity启动模式
- 导出网页中的table到excel
- Python future模块小例子
- Boosting学习(三)—Adaboost原理白话
- cv1.0入门
- HDOJ 4722Good Numbers 数位DP
- 轻松把玩HttpClient之配置ssl,采用设置信任自签名证书实现https
- dwr
- 函数后面加const修饰
- "undefinedreference to '__gxx_personality_v0' " 错误
- Latex常用语法总结
- JAVA常用文件工具类
- 单例模式的八种写法比较、枚举实现的好处、静态内部类实现单例原理