zoukankan      html  css  js  c++  java
  • cv1.0入门

    作者 群号 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 <opencv2highguihighgui.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 <opencv2opencv.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 <opencv2opencv.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 <opencv2opencv.hpp>
    #include <iostream>
    using namespace cv;
    using namespace std;
    
    #include <math.h>
    #define PI 3.14159265358979
    
    int 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 <opencv2opencv.hpp>
    #include <iostream>
    using namespace cv;
    using namespace std;
    
    #include <math.h>
    #define PI 3.14159265358979
    class 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 line
    public:
        // 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=	y=	r=" << 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]) << "	" << cvRound(circles[i][1]) << "	" 
    		     << 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 trackbar
    void 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 trackbar void 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: " " ESC - quit the program " " r - use rectangle structuring element " " e - use elliptic structuring element " " c - use cross-shaped structuring element " " ENTER - loop through all the options " ); 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 == ' ' ) 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 images
    IplImage* 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 callback
    void 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: 
    "
            "	ESC - quit the program
    "
            "	3 - use 3x3 mask
    "
            "	5 - use 5x5 mask
    "
            "	0 - use precise distance transform
    "
            "	v - switch Voronoi diagram mode on/off
    "
            "	ENTER - loop through all the modes
    " );
        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 == '
    ' )
            {
                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;
    }
    







  • 相关阅读:
    Python Generators vs Iterators
    python staticmethod classmethod
    静态类型、动态类型、强类型以及弱类型语言
    Python串行运算、并行运算、多线程、多进程对比实验
    python字典根据value排序
    解读Python内存管理机制
    两个list 求交集效率对比
    Python error: Unable to find vcvarsall.bat
    max-length兼容ie
    return false 与return true 困惑
  • 原文地址:https://www.cnblogs.com/llguanli/p/8776321.html
Copyright © 2011-2022 走看看