opencv1.0

来源:互联网 发布:电梯仿真软件 编辑:程序博客网 时间:2024/05/20 18:50

环境

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;}

0 0
原创粉丝点击