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

1.图像特征匹配

 // AxFeatureExtract.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include "opencv2/opencv.hpp"
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/nonfree/nonfree.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include "vector" using namespace std; int _tmain(int argc, _TCHAR* argv[])
{
cv::Mat rgb1 = cv::imread( "G:\\SLAMDatasets\\一起做RGB-DSLAM数据\\rgb_png\\1.png");
cv::Mat rgb2 = cv::imread( "G:\\SLAMDatasets\\一起做RGB-DSLAM数据\\rgb_png\\2.png");
cv::Mat depth1 = cv::imread( "G:\\SLAMDatasets\\一起做RGB-DSLAM数据\\depth_png\\1.png", -);
cv::Mat depth2 = cv::imread( "G:\\SLAMDatasets\\一起做RGB-DSLAM数据\\depth_png\\2.png", -); // 声明特征提取器与描述子提取器
cv::Ptr<cv::FeatureDetector> _detector;
cv::Ptr<cv::DescriptorExtractor> _descriptor; // 构建提取器,默认两者都为sift
// 构建sift, surf之前要初始化nonfree模块
cv::initModule_nonfree();
_detector = cv::FeatureDetector::create( "GridSIFT" );
_descriptor = cv::DescriptorExtractor::create( "SIFT" ); vector< cv::KeyPoint > kp1, kp2; //关键点
_detector->detect( rgb1, kp1 ); //提取关键点
_detector->detect( rgb2, kp2 ); cout<<"Key points of two images: "<<kp1.size()<<", "<<kp2.size()<<endl; // 可视化, 显示关键点
cv::Mat imgShow;
cv::drawKeypoints( rgb1, kp1, imgShow, cv::Scalar::all(-), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS );
cv::imshow( "keypoints", imgShow );
cv::imwrite( "data\\keypoints.png", imgShow );
cv::waitKey(); //暂停等待一个按键 // 计算描述子
cv::Mat desp1, desp2;
_descriptor->compute( rgb1, kp1, desp1 );
_descriptor->compute( rgb2, kp2, desp2 ); // 匹配描述子
vector< cv::DMatch > matches;
cv::FlannBasedMatcher matcher;
matcher.match( desp1, desp2, matches );
cout<<"Find total "<<matches.size()<<" matches."<<endl; // 可视化:显示匹配的特征
cv::Mat imgMatches;
cv::drawMatches( rgb1, kp1, rgb2, kp2, matches, imgMatches );
cv::imshow( "matches", imgMatches );
cv::imwrite( "data\\matches.png", imgMatches );
cv::waitKey( ); // 筛选匹配,把距离太大的去掉
// 这里使用的准则是去掉大于四倍最小距离的匹配
vector< cv::DMatch > goodMatches;
double minDis = ;
for ( size_t i=; i<matches.size(); i++ )
{
if ( matches[i].distance < minDis )
minDis = matches[i].distance;
} for ( size_t i=; i<matches.size(); i++ )
{
if (matches[i].distance < *minDis)
goodMatches.push_back( matches[i] );
} // 显示 good matches
cout<<"good matches="<<goodMatches.size()<<endl;
cv::drawMatches( rgb1, kp1, rgb2, kp2, goodMatches, imgMatches );
cv::imshow( "good matches", imgMatches );
cv::imwrite( "data\\good_matches.png", imgMatches );
system("pause");
return ;
}

2.膨胀和侵蚀

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

 // AxFeatureExtract.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include "opencv2/opencv.hpp"
#include <opencv2/core/core.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/nonfree/nonfree.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "vector" using namespace std;
using namespace cv; int _tmain(int argc, _TCHAR* argv[])
{
cv::Mat rgb1 = cv::imread( "G:\\SLAMDatasets\\一起做RGB-DSLAM数据\\rgb_png\\1.png");
cv::Mat depth1 = cv::imread( "G:\\SLAMDatasets\\一起做RGB-DSLAM数据\\depth_png\\1.png", -); cv::imshow( "matches", rgb1 );
cv::Mat elementdilate = getStructuringElement(MORPH_RECT, Size(, ));
cv::Mat outdilate;
//进行膨胀操作
dilate(rgb1, outdilate, elementdilate);
cv::imshow( "dilate", outdilate );
cv::imwrite( "data\\dilate.png", outdilate );
cv::waitKey( ); cv::Mat elementerode = getStructuringElement(MORPH_RECT, Size(, ));
cv::Mat outerode; //进行腐蚀操作
erode(depth1,outerode, elementerode);
cv::imshow( "erode", outerode );
cv::imwrite( "data\\outerode.png", outerode );
system("pause");
return ;
}

3.图像二值化

4.图像边缘提取

 // AxFeatureExtract.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include "opencv2/opencv.hpp"
#include <opencv2/core/core.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/nonfree/nonfree.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "vector" using namespace std;
using namespace cv;
void RemoveSmallRegion(Mat& Src, Mat& Dst, int AreaLimit=, int CheckMode=, int NeihborMode=); int _tmain(int argc, _TCHAR* argv[])
{
cv::Mat rgb1 = cv::imread( "data\\dump-00050.png");
cv::imshow( "dump", rgb1 ); cv::waitKey( );
//提取边缘
cv::Mat src=rgb1.clone();
cv::Mat dstSobel;
Sobel(src,dstSobel,src.depth(),,);
cv::imshow( "Sobel", dstSobel );
imwrite("sobel.jpg",dstSobel); cv::Mat dstLaplacian;
Laplacian(src,dstLaplacian,src.depth());
cv::imshow("Laplacian", dstLaplacian );
imwrite("laplacian.jpg",dstLaplacian); cv::Mat g_grayImage;
cv::Mat dstCanny;
cvtColor(src,g_grayImage,CV_BGR2GRAY); //canny只处理灰度图
Canny(g_grayImage,dstCanny,,,);
cv::imshow("Canny", dstCanny );
imwrite("canny.jpg",dstCanny); cv::Mat g_dstImage;
threshold(g_grayImage,g_dstImage,,,CV_THRESH_BINARY_INV); //大津阈值
imshow("threshold",g_dstImage);
imwrite("threshold.jpg",g_dstImage); cv::Mat elementdilate = getStructuringElement(MORPH_RECT, Size(, ));
cv::Mat outdilate;
//进行膨胀操作
dilate(g_dstImage, outdilate, elementdilate);
cv::imshow( "dilate", outdilate );
//cv::imwrite( "data\\dilate.png", outdilate ); cv::Mat outresult;
cv::Mat image=dstLaplacian.clone();
cv::subtract(dstCanny, outdilate, outresult);//注意保证两个图像的格式一致
cv::imshow( "frontier", outresult ); Mat rgb2 = Mat::zeros(outresult.size(), CV_8UC1);
/*blur(outresult,rgb2,Size(3,3),Point(-1,-1));
cv::imshow( "blur", rgb2 );*/
RemoveSmallRegion(outresult,rgb2,,, );
cv::imshow( "blur", rgb2 );
cv::waitKey( );
system("pause");
return ;
} void RemoveSmallRegion(Mat& Src, Mat& Dst, int AreaLimit, int CheckMode, int NeihborMode)
{
int RemoveCount=; //记录除去的个数
//记录每个像素点检验状态的标签,0代表未检查,1代表正在检查,2代表检查不合格(需要反转颜色),3代表检查合格或不需检查
Mat Pointlabel = Mat::zeros( Src.size(), CV_8UC1 ); if(CheckMode==)
{
cout<<"Mode: 去除小区域. ";
for(int i = ; i < Src.rows; ++i)
{
uchar* iData = Src.ptr<uchar>(i);
uchar* iLabel = Pointlabel.ptr<uchar>(i);
for(int j = ; j < Src.cols; ++j)
{
if (iData[j] < )
{
iLabel[j] = ;
}
}
}
}
else
{
cout<<"Mode: 去除孔洞. ";
for(int i = ; i < Src.rows; ++i)
{
uchar* iData = Src.ptr<uchar>(i);
uchar* iLabel = Pointlabel.ptr<uchar>(i);
for(int j = ; j < Src.cols; ++j)
{
if (iData[j] > )
{
iLabel[j] = ;
}
}
}
} vector<Point2i> NeihborPos; //记录邻域点位置
NeihborPos.push_back(Point2i(-, ));
NeihborPos.push_back(Point2i(, ));
NeihborPos.push_back(Point2i(, -));
NeihborPos.push_back(Point2i(, ));
if (NeihborMode==)
{
cout<<"Neighbor mode: 8邻域."<<endl;
NeihborPos.push_back(Point2i(-, -));
NeihborPos.push_back(Point2i(-, ));
NeihborPos.push_back(Point2i(, -));
NeihborPos.push_back(Point2i(, ));
}
else cout<<"Neighbor mode: 4邻域."<<endl;
int NeihborCount=+*NeihborMode;
int CurrX=, CurrY=;
//开始检测
for(int i = ; i < Src.rows; ++i)
{
uchar* iLabel = Pointlabel.ptr<uchar>(i);
for(int j = ; j < Src.cols; ++j)
{
if (iLabel[j] == )
{
//********开始该点处的检查**********
vector<Point2i> GrowBuffer; //堆栈,用于存储生长点
GrowBuffer.push_back( Point2i(j, i) );
Pointlabel.at<uchar>(i, j)=;
int CheckResult=; //用于判断结果(是否超出大小),0为未超出,1为超出 for ( int z=; z<GrowBuffer.size(); z++ )
{ for (int q=; q<NeihborCount; q++) //检查四个邻域点
{
CurrX=GrowBuffer.at(z).x+NeihborPos.at(q).x;
CurrY=GrowBuffer.at(z).y+NeihborPos.at(q).y;
if (CurrX>=&&CurrX<Src.cols&&CurrY>=&&CurrY<Src.rows) //防止越界
{
if ( Pointlabel.at<uchar>(CurrY, CurrX)== )
{
GrowBuffer.push_back( Point2i(CurrX, CurrY) ); //邻域点加入buffer
Pointlabel.at<uchar>(CurrY, CurrX)=; //更新邻域点的检查标签,避免重复检查
}
}
} }
if (GrowBuffer.size()>AreaLimit) CheckResult=; //判断结果(是否超出限定的大小),1为未超出,2为超出
else {CheckResult=; RemoveCount++;}
for (int z=; z<GrowBuffer.size(); z++) //更新Label记录
{
CurrX=GrowBuffer.at(z).x;
CurrY=GrowBuffer.at(z).y;
Pointlabel.at<uchar>(CurrY, CurrX) += CheckResult;
}
//********结束该点处的检查********** }
}
} CheckMode=*(-CheckMode);
//开始反转面积过小的区域
for(int i = ; i < Src.rows; ++i)
{
uchar* iData = Src.ptr<uchar>(i);
uchar* iDstData = Dst.ptr<uchar>(i);
uchar* iLabel = Pointlabel.ptr<uchar>(i);
for(int j = ; j < Src.cols; ++j)
{
if (iLabel[j] == )
{
iDstData[j] = CheckMode;
}
else if(iLabel[j] == )
{
iDstData[j] = iData[j];
}
}
} cout<<RemoveCount<<" objects removed."<<endl;
}

[OpenCV]代码整理的更多相关文章

  1. Smtp邮件发送系统公用代码整理—总结

    1.前言 a.在软件开发中,我们经常能够遇到给用户或者客户推送邮件,推送邮件也分为很多方式,比如:推送一句话,推送一个网页等等.那么在系统开发中我们一般在什么情况下会使用邮件发送呢?下面我简单总结了一 ...

  2. Chrome应用技巧之代码整理。

    我们有时候在看别人站点代码时往往是经过压缩的,代码都在一行上了,调试非常是困难,今天给大家介绍一种基本Chrome浏览器的代码整理方法.请看图:

  3. NSIS常用代码整理

    原文 NSIS常用代码整理 这是一些常用的NSIS代码,少轻狂特意整理出来,方便大家随时查看使用.不定期更新哦~~~ 1 ;获取操作系统盘符 2 ReadEnvStr $R0 SYSTEMDRIVE ...

  4. material design 的android开源代码整理

    material design 的android开源代码整理 1 android (material design 效果的代码库) 地址请点击:MaterialDesignLibrary 效果: 2 ...

  5. HTTP请求代码整理

    HTTP请求代码整理 类别 代码 注释 1xx – 信息提示 100 继续 101 切换协议 2xx - 成功 200 确定.客户端请求已成功 201 已创建 202 已接受 203 非权威性信息 2 ...

  6. SQL代码整理

    --SQL代码整理: create database mingzi--创建数据库go--连接符(可省略)create table biao--创建表( lieming1 int not null,-- ...

  7. IOS常用代码整理

    常用代码整理: 12.判断邮箱格式是否正确的代码: //利用正则表达式验证 -(BOOL)isValidateEmail:(NSString *)email { NSString *emailRege ...

  8. html Css PC 移动端 公用部分样式代码整理

    css常用公用部分样式代码整理: body, html, div, blockquote, img, label, p, h1, h2, h3, h4, h5, h6, pre, ul, ol, li ...

  9. Photon Server 实现注册与登录(二) --- 服务端代码整理

    一.有的代码前端和后端都会用到.比如一些请求的Code.使用需要新建项目存放公共代码. 新建项目Common存放公共代码: EventCode :存放服务端自动发送信息给客户端的code Operat ...

随机推荐

  1. jquery-ui弹框登录前端写法

    新建一个div: <div class="container" id="loginForm" hidden> <h4 class=" ...

  2. linux相关(3)

    1. shell环境变量 能够存在于本shell进程及其子shell进程的变量.变量可以从父shell进程传递给子shell进程,而不能反过来,因此环境变量在子shell进程中无论如何修改都不会影响到 ...

  3. Phoenix系列:原子的Upsert

    Phoenix的插入语句是Upsert,Update和Insert的组合语义.即,如果数据表中没有这条记录那么插入这条记录,如果有则更新.判断是否存在相同的数据是使用ON DUPLICATE KEY来 ...

  4. 终于知道什么情况下需要实现.NET Core中的IOptions接口

    自从接触 IOptions 之后,一直纠结这样的问题:自己定义的 Options 要不要实现 IOptions 接口. 微软有的项目中实现了,比如 Caching 中的 MemoryCacheOpti ...

  5. 信1705-2 软工作业最大重复词查询思路: (1)将文章(一个字符串存储)按空格进行拆分(split)后,存储到一个字符串(单词)数组中。 (2)定义一个Map,key是字符串类型,保存单词;value是数字类型,保存该单词出现的次数。 (3)遍历(1)中得到的字符串数组,对于每一个单词,考察Map的key中是否出现过该单词,如果没出现过,map中增加一个元素,key为该单词,value为1(

    通过学习学会了文本的访问,了解一点哈希表用途.经过网上查找做成了下面查询文章重复词的JAVA程序. 1 思 思路: (1)将文章(一个字符串存储)按空格进行拆分(split)后,存储到一个字符串(单词 ...

  6. hhvm

    hhvm(Hip Virtual Machine),是一个虚拟机,用来运行PHP的 hhvm是有Facebook开发的,用户提升PHP性能的,hhvm是开源的,

  7. mysql缓冲

  8. PHP进阶-浏览器到PHP发展历史

    从浏览器到PHP发展历史 php-cgi实现cgi的解析器,每个fork过程都开启一个进程,并会进行一个关闭进程的操作. 长注内存解释器(一个进程) fastcgi 多进程共享一个端口是一个问题,多进 ...

  9. [development][security][suricata] suricata 使用与调研

    0: OISF:https://oisf.net/ 1: suricata是什么 https://suricata-ids.org/ 2:安装 https://redmine.openinfosecf ...

  10. java 之程序中的http请求

    背景 java程序中有时需要我们发起http级别的请求,例如抓数据或者第三方对接时,一般分为两种:一种是只需我们发起请求,还有一种是我们不但要发起请求,还要拿到请求后的数据来进行下一步处理 实现 针对 ...