[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 }  
原文地址:https://www.cnblogs.com/yhlx125/p/6957177.html