• [OpenCV]代码整理


    开发环境:Windows7, VS2010, OpenCV2.4.10

    1.图像特征匹配

     1 // AxFeatureExtract.cpp : 定义控制台应用程序的入口点。
     2 //
     3 
     4 #include "stdafx.h"
     5 #include "opencv2/opencv.hpp"
     6 #include <opencv2/features2d/features2d.hpp>
     7 #include <opencv2/nonfree/nonfree.hpp>
     8 #include <opencv2/calib3d/calib3d.hpp>
     9 #include "vector"
    10 
    11 using namespace std;
    12 
    13 int _tmain(int argc, _TCHAR* argv[])
    14 {
    15     cv::Mat rgb1 = cv::imread( "G:\SLAMDatasets\一起做RGB-DSLAM数据\rgb_png\1.png");
    16     cv::Mat rgb2 = cv::imread( "G:\SLAMDatasets\一起做RGB-DSLAM数据\rgb_png\2.png");
    17     cv::Mat depth1 = cv::imread( "G:\SLAMDatasets\一起做RGB-DSLAM数据\depth_png\1.png", -1);
    18     cv::Mat depth2 = cv::imread( "G:\SLAMDatasets\一起做RGB-DSLAM数据\depth_png\2.png", -1);
    19      
    20     // 声明特征提取器与描述子提取器
    21     cv::Ptr<cv::FeatureDetector> _detector;
    22     cv::Ptr<cv::DescriptorExtractor> _descriptor;
    23     
    24     // 构建提取器,默认两者都为sift
    25     // 构建sift, surf之前要初始化nonfree模块
    26     cv::initModule_nonfree();
    27     _detector = cv::FeatureDetector::create( "GridSIFT" );
    28     _descriptor = cv::DescriptorExtractor::create( "SIFT" );
    29      
    30     vector< cv::KeyPoint > kp1, kp2; //关键点
    31     _detector->detect( rgb1, kp1 );  //提取关键点
    32     _detector->detect( rgb2, kp2 );
    33     
    34     cout<<"Key points of two images: "<<kp1.size()<<", "<<kp2.size()<<endl;
    35         
    36     // 可视化, 显示关键点
    37     cv::Mat imgShow;
    38     cv::drawKeypoints( rgb1, kp1, imgShow, cv::Scalar::all(-1), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS );
    39     cv::imshow( "keypoints", imgShow );
    40     cv::imwrite( "data\keypoints.png", imgShow );
    41     cv::waitKey(0); //暂停等待一个按键
    42        
    43     // 计算描述子
    44     cv::Mat desp1, desp2;
    45     _descriptor->compute( rgb1, kp1, desp1 );
    46     _descriptor->compute( rgb2, kp2, desp2 );
    47     
    48     // 匹配描述子
    49     vector< cv::DMatch > matches; 
    50     cv::FlannBasedMatcher matcher;
    51     matcher.match( desp1, desp2, matches );
    52     cout<<"Find total "<<matches.size()<<" matches."<<endl;
    53     
    54     // 可视化:显示匹配的特征
    55     cv::Mat imgMatches;
    56     cv::drawMatches( rgb1, kp1, rgb2, kp2, matches, imgMatches );
    57     cv::imshow( "matches", imgMatches );
    58     cv::imwrite( "data\matches.png", imgMatches );
    59     cv::waitKey( 0 );
    60     
    61     // 筛选匹配,把距离太大的去掉
    62     // 这里使用的准则是去掉大于四倍最小距离的匹配
    63     vector< cv::DMatch > goodMatches;
    64     double minDis = 9999;
    65     for ( size_t i=0; i<matches.size(); i++ )
    66     {
    67             if ( matches[i].distance < minDis )
    68                 minDis = matches[i].distance;
    69     }
    70     
    71     for ( size_t i=0; i<matches.size(); i++ )
    72     {
    73         if (matches[i].distance < 4*minDis)
    74             goodMatches.push_back( matches[i] );
    75     }
    76 
    77         // 显示 good matches
    78     cout<<"good matches="<<goodMatches.size()<<endl;
    79     cv::drawMatches( rgb1, kp1, rgb2, kp2, goodMatches, imgMatches );
    80     cv::imshow( "good matches", imgMatches );
    81     cv::imwrite( "data\good_matches.png", imgMatches );
    82     system("pause");
    83     return 0;
    84 }

    2.膨胀和侵蚀

    形态学方法:读取图像,实现图像的膨胀和侵蚀操作。

     1 // AxFeatureExtract.cpp : 定义控制台应用程序的入口点。
     2 //
     3 
     4 #include "stdafx.h"
     5 #include "opencv2/opencv.hpp"
     6 #include <opencv2/core/core.hpp>  
     7 #include <opencv2/features2d/features2d.hpp>
     8 #include <opencv2/nonfree/nonfree.hpp>
     9 #include <opencv2/calib3d/calib3d.hpp>
    10 #include <opencv2/imgproc/imgproc.hpp> 
    11 #include "vector"
    12 
    13 using namespace std;
    14 using namespace cv; 
    15 
    16 int _tmain(int argc, _TCHAR* argv[])
    17 {
    18     cv::Mat rgb1 = cv::imread( "G:\SLAMDatasets\一起做RGB-DSLAM数据\rgb_png\1.png");
    19     cv::Mat depth1 = cv::imread( "G:\SLAMDatasets\一起做RGB-DSLAM数据\depth_png\1.png", -1);
    20 
    21     cv::imshow( "matches", rgb1 );
    22     cv::Mat elementdilate = getStructuringElement(MORPH_RECT, Size(15, 15));  
    23     cv::Mat outdilate;  
    24     //进行膨胀操作  
    25     dilate(rgb1, outdilate, elementdilate); 
    26     cv::imshow( "dilate", outdilate );
    27     cv::imwrite( "data\dilate.png", outdilate );
    28     cv::waitKey( 0 );
    29 
    30     cv::Mat elementerode = getStructuringElement(MORPH_RECT, Size(15, 15));  
    31     cv::Mat outerode;  
    32 
    33     //进行腐蚀操作  
    34     erode(depth1,outerode, elementerode);  
    35     cv::imshow( "erode", outerode );
    36     cv::imwrite( "data\outerode.png", outerode );
    37     system("pause");
    38     return 0;
    39 }

    3.图像二值化

    4.图像边缘提取

      1 // AxFeatureExtract.cpp : 定义控制台应用程序的入口点。
      2 //
      3 
      4 #include "stdafx.h"
      5 #include "opencv2/opencv.hpp"
      6 #include <opencv2/core/core.hpp>  
      7 #include <opencv2/features2d/features2d.hpp>
      8 #include <opencv2/nonfree/nonfree.hpp>
      9 #include <opencv2/calib3d/calib3d.hpp>
     10 #include <opencv2/imgproc/imgproc.hpp> 
     11 #include "vector"
     12 
     13 using namespace std;
     14 using namespace cv; 
     15 void RemoveSmallRegion(Mat& Src, Mat& Dst, int AreaLimit=50, int CheckMode=1, int NeihborMode=0);
     16 
     17 int _tmain(int argc, _TCHAR* argv[])
     18 {
     19     cv::Mat rgb1 = cv::imread( "data\dump-00050.png");
     20     cv::imshow( "dump", rgb1 );
     21     
     22     
     23 
     24     cv::waitKey( 0 );
     25     //提取边缘
     26     cv::Mat src=rgb1.clone();
     27     cv::Mat dstSobel;
     28     Sobel(src,dstSobel,src.depth(),1,1);
     29     cv::imshow( "Sobel", dstSobel );
     30     imwrite("sobel.jpg",dstSobel);
     31 
     32     cv::Mat dstLaplacian;
     33     Laplacian(src,dstLaplacian,src.depth());
     34     cv::imshow("Laplacian", dstLaplacian );
     35     imwrite("laplacian.jpg",dstLaplacian);
     36 
     37     cv::Mat g_grayImage;
     38     cv::Mat dstCanny;
     39     cvtColor(src,g_grayImage,CV_BGR2GRAY);  //canny只处理灰度图
     40     Canny(g_grayImage,dstCanny,50,150,3);
     41     cv::imshow("Canny", dstCanny );
     42     imwrite("canny.jpg",dstCanny);
     43 
     44 
     45     cv::Mat g_dstImage;
     46     threshold(g_grayImage,g_dstImage,125,255,CV_THRESH_BINARY_INV);  //大津阈值  
     47     imshow("threshold",g_dstImage); 
     48     imwrite("threshold.jpg",g_dstImage);
     49 
     50     cv::Mat elementdilate = getStructuringElement(MORPH_RECT, Size(5, 5));  
     51     cv::Mat outdilate;  
     52     //进行膨胀操作  
     53     dilate(g_dstImage, outdilate, elementdilate); 
     54     cv::imshow( "dilate", outdilate );
     55     //cv::imwrite( "data\dilate.png", outdilate );
     56 
     57     cv::Mat outresult;  
     58     cv::Mat image=dstLaplacian.clone();
     59     cv::subtract(dstCanny,  outdilate,  outresult);//注意保证两个图像的格式一致
     60     cv::imshow( "frontier", outresult );
     61 
     62     Mat rgb2 = Mat::zeros(outresult.size(), CV_8UC1);  
     63     /*blur(outresult,rgb2,Size(3,3),Point(-1,-1));
     64     cv::imshow( "blur", rgb2 );*/
     65     RemoveSmallRegion(outresult,rgb2,10,1, 1);
     66     cv::imshow( "blur", rgb2 );
     67     cv::waitKey( 0 );
     68     system("pause");
     69     return 0;
     70 }
     71 
     72 void RemoveSmallRegion(Mat& Src, Mat& Dst, int AreaLimit, int CheckMode, int NeihborMode)  
     73 {     
     74     int RemoveCount=0;       //记录除去的个数  
     75     //记录每个像素点检验状态的标签,0代表未检查,1代表正在检查,2代表检查不合格(需要反转颜色),3代表检查合格或不需检查  
     76     Mat Pointlabel = Mat::zeros( Src.size(), CV_8UC1 );  
     77       
     78     if(CheckMode==1)  
     79     {  
     80         cout<<"Mode: 去除小区域. ";  
     81         for(int i = 0; i < Src.rows; ++i)    
     82         {    
     83             uchar* iData = Src.ptr<uchar>(i);  
     84             uchar* iLabel = Pointlabel.ptr<uchar>(i);  
     85             for(int j = 0; j < Src.cols; ++j)    
     86             {    
     87                 if (iData[j] < 10)    
     88                 {    
     89                     iLabel[j] = 3;   
     90                 }    
     91             }    
     92         }    
     93     }  
     94     else  
     95     {  
     96         cout<<"Mode: 去除孔洞. ";  
     97         for(int i = 0; i < Src.rows; ++i)    
     98         {    
     99             uchar* iData = Src.ptr<uchar>(i);  
    100             uchar* iLabel = Pointlabel.ptr<uchar>(i);  
    101             for(int j = 0; j < Src.cols; ++j)    
    102             {    
    103                 if (iData[j] > 10)    
    104                 {    
    105                     iLabel[j] = 3;   
    106                 }    
    107             }    
    108         }    
    109     }  
    110   
    111     vector<Point2i> NeihborPos;  //记录邻域点位置  
    112     NeihborPos.push_back(Point2i(-1, 0));  
    113     NeihborPos.push_back(Point2i(1, 0));  
    114     NeihborPos.push_back(Point2i(0, -1));  
    115     NeihborPos.push_back(Point2i(0, 1));  
    116     if (NeihborMode==1)  
    117     {  
    118         cout<<"Neighbor mode: 8邻域."<<endl;  
    119         NeihborPos.push_back(Point2i(-1, -1));  
    120         NeihborPos.push_back(Point2i(-1, 1));  
    121         NeihborPos.push_back(Point2i(1, -1));  
    122         NeihborPos.push_back(Point2i(1, 1));  
    123     }  
    124     else cout<<"Neighbor mode: 4邻域."<<endl;  
    125     int NeihborCount=4+4*NeihborMode;  
    126     int CurrX=0, CurrY=0;  
    127     //开始检测  
    128     for(int i = 0; i < Src.rows; ++i)    
    129     {    
    130         uchar* iLabel = Pointlabel.ptr<uchar>(i);  
    131         for(int j = 0; j < Src.cols; ++j)    
    132         {    
    133             if (iLabel[j] == 0)    
    134             {    
    135                 //********开始该点处的检查**********  
    136                 vector<Point2i> GrowBuffer;                                      //堆栈,用于存储生长点  
    137                 GrowBuffer.push_back( Point2i(j, i) );  
    138                 Pointlabel.at<uchar>(i, j)=1;  
    139                 int CheckResult=0;                                               //用于判断结果(是否超出大小),0为未超出,1为超出  
    140   
    141                 for ( int z=0; z<GrowBuffer.size(); z++ )  
    142                 {  
    143   
    144                     for (int q=0; q<NeihborCount; q++)                                      //检查四个邻域点  
    145                     {  
    146                         CurrX=GrowBuffer.at(z).x+NeihborPos.at(q).x;  
    147                         CurrY=GrowBuffer.at(z).y+NeihborPos.at(q).y;  
    148                         if (CurrX>=0&&CurrX<Src.cols&&CurrY>=0&&CurrY<Src.rows)  //防止越界  
    149                         {  
    150                             if ( Pointlabel.at<uchar>(CurrY, CurrX)==0 )  
    151                             {  
    152                                 GrowBuffer.push_back( Point2i(CurrX, CurrY) );  //邻域点加入buffer  
    153                                 Pointlabel.at<uchar>(CurrY, CurrX)=1;           //更新邻域点的检查标签,避免重复检查  
    154                             }  
    155                         }  
    156                     }  
    157   
    158                 }  
    159                 if (GrowBuffer.size()>AreaLimit) CheckResult=2;                 //判断结果(是否超出限定的大小),1为未超出,2为超出  
    160                 else {CheckResult=1;   RemoveCount++;}  
    161                 for (int z=0; z<GrowBuffer.size(); z++)                         //更新Label记录  
    162                 {  
    163                     CurrX=GrowBuffer.at(z).x;   
    164                     CurrY=GrowBuffer.at(z).y;  
    165                     Pointlabel.at<uchar>(CurrY, CurrX) += CheckResult;  
    166                 }  
    167                 //********结束该点处的检查**********  
    168   
    169   
    170             }    
    171         }    
    172     }    
    173   
    174     CheckMode=255*(1-CheckMode);  
    175     //开始反转面积过小的区域  
    176     for(int i = 0; i < Src.rows; ++i)    
    177     {    
    178         uchar* iData = Src.ptr<uchar>(i);  
    179         uchar* iDstData = Dst.ptr<uchar>(i);  
    180         uchar* iLabel = Pointlabel.ptr<uchar>(i);  
    181         for(int j = 0; j < Src.cols; ++j)    
    182         {    
    183             if (iLabel[j] == 2)    
    184             {    
    185                 iDstData[j] = CheckMode;   
    186             }    
    187             else if(iLabel[j] == 3)  
    188             {  
    189                 iDstData[j] = iData[j];  
    190             }  
    191         }    
    192     }   
    193       
    194     cout<<RemoveCount<<" objects removed."<<endl;  
    195 }  
  • 相关阅读:
    CSS自动控制图片大小的代码
    JS 判断 Radio 单选按钮是否为选中状态 并弹出 值信息
    [转]eclipse github 提交代码
    WEB 开发工具分享
    javaShop的一些总结
    前端进阶试题(css部分)
    如何判断浏览器 然后针对不同的浏览器加入单独的样式
    jquery 提示信息显示后自动消失的具体实现
    html a标签 图片边框和点击后虚线框的有关问题
    html 包含一个公共文件
  • 原文地址:https://www.cnblogs.com/yhlx125/p/6957177.html
Copyright © 2020-2023  润新知