[OpenCV]代码整理

时间:2022-12-30 15:17:44

开发环境: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 实现注册与登录&lpar;二&rpar; --- 服务端代码整理

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

随机推荐

  1. dp --- CSU 1547&colon; Rectangle

    Rectangle Problem's Link:   http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1547 Mean: 给你一些宽为1或2 的木 ...

  2. php 格式化数字 位数不足前面加0补足

    本文引用自 http://www.fengfly.com/plus/view-62827-1.html 补0: <?php $var = sprintf("%03d", 12 ...

  3. div&plus;css登陆界面案例2

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. 今天知道了一个 反向代理,是apache 的一个功能,这里记录一下

    什么事情都需要自己 去弄,记住了这句话,不要以为 别人会来帮你 在 apache 的http.conf 文件中(去掉注释) LoadModule proxy_module modules/mod_pr ...

  5. AIX逻辑卷扩容

    aix的文件系统扩容是非常灵活的,如果不涉及加硬盘的硬件操作,只要通过aix里面的命令或者smitty菜单就行了,当然做好数据备份在任何情况下都是必要的. 1. 查看个逻辑卷大小 # df -gFil ...

  6. JDBC 连接Oracle

    工作中,我们遇到的操作数据库代码都是封装起来的,今天我们就来看看,最基本的利用JDBC来操作数据库. JDBC连接数据库主要有三个步骤: 第一步:加载数据库驱动.通常我们使用Class.forName ...

  7. JavaWeb学习 &lpar;二十四&rpar;————Filter&lpar;过滤器&rpar;常见应用

    一.统一全站字符编码 通过配置参数charset指明使用何种字符编码,以处理Html Form请求参数的中文问题 1 package me.gacl.web.filter; 2 3 import ja ...

  8. mysqldump 用法

    mysqldump 是文本备份还是二进制备份 它是文本备份,如果你打开备份文件你将看到所有的语句,可以用于重新创建表和对象.它也有 insert 语句来使用数据构成表. mysqldump 的语法是什 ...

  9. XenServer:使用XenCenter开设VPS&lpar;多图完整版&rpar;

    打铁要趁热,咱们接着来玩XenServer.昨天赵容用机房提供的KVM给服务器装了XenServer,今天我们来玩更有意思的:开小鸡.装好XenServer之后,访问我们的服务器IP,就可以看到Xen ...

  10. shell 布尔运算符

    布尔运算符 下表列出了常用的布尔运算符,假定变量 a 为 10,变量 b 为 20: 运算符 说明 举例 ! 非运算,表达式为 true 则返回 false,否则返回 true. [ ! false ...