answerOpenCV轮廓类问题解析
contour在opencv中是一个基础的数据结构,灵活运用的话,作用很大。以contour为关键字,在answerOpenCV中能够发现很多有趣的东西。


How to find dimensions of an object in the image
这道题厉害了,一看这个需求就是专业的:
I want to find the length of an object in the image (image length not the real physical length). My first idea is was to use boundingRect to find the dimensions, but some of the masks I have split in between them so the boundingRect method fails. Can someone suggest me a robust method to find the length of the object in the given mask
他需要从这个图中活动轮廓的长度(这个应该是一个脚印),但是因为图上轮廓可能有多个,所以不知道怎么办。
解析:这道题的关键,就在于实际上,每张图的轮廓只有一个。这是重要的先验条件。那怎么办?把识别出来的轮廓连起来呀。
连的方法有多种,我给出两种比较保险:
1、形态学变化
dilate(bw,bw,Mat(11,11,CV_8UC1));
erode(bw,bw,Mat(11,11,CV_8UC1));
2、实在距离太远,靠不上了,直接把中线连起来吧
由于这道题目前还没有比较好的解决方法,所以我实现了一个,应该是可以用的,这是结果:
网站代码也已经提交到网站上了
//程序主要部分
int main( int argc, char** argv )
{
//读入图像,转换为灰度
Mat img = imread("e:/sandbox/1234.png");
Mat bw;
bool dRet;
cvtColor(img, bw, COLOR_BGR2GRAY);
//阈值处理
threshold(bw, bw, 150, 255, CV_THRESH_BINARY);
bitwise_not(bw,bw);
//形态学变化
dilate(bw,bw,Mat(11,11,CV_8UC1));
erode(bw,bw,Mat(11,11,CV_8UC1));
//寻找轮廓
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(bw, contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
/// 计算矩
vector<Moments> mu(contours.size() );
for( int i = 0; i < contours.size(); i++ )
mu[i] = moments( contours[i], false );
/// 计算中心矩:
vector<Point2f> mc( contours.size() );
for( int i = 0; i < contours.size(); i++ )
mc[i] = Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 );
//connect all contours into ONE
for (int i = 0; i < contours.size(); ++i)
{
Scalar color = Scalar( rng12345.uniform(0, 255), rng12345.uniform(0,255), rng12345.uniform(0,255) );
drawContours( img, contours, i, color, 2, 8, hierarchy, 0, Point() );
circle( img, mc[i], 4, color, -1, 8, 0 );
//connect
if (i+1 <contours.size())
line(bw,mc[i],mc[i+1],Scalar(255,255,255));
}
contours.clear();
hierarchy.clear();
//寻找结果
findContours(bw, contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
for (int i = 0;i<contours.size();i++)
{
RotatedRect minRect = minAreaRect( Mat(contours[i]) );
Point2f rect_points[4];
minRect.points( rect_points );
for( int j = 0; j < 4; j++ )
line( img, rect_points[j], rect_points[(j+1)%4],Scalar(255,255,0),2);
float fshort = std::min(minRect.size.width,minRect.size.height); //short
float flong = std::max(minRect.size.width,minRect.size.height); //long
}
imshow("img",img);
waitKey();
return 0;
}
3、新函数
Orientation of two contours
这个topic希望能够获得两个轮廓之间的角度。并且后期通过旋转将两者重合。
I try to calculate the orientation of 2 contours. At the end i want to rotate one contour, so it is in cover with the other one. With my code I get a result, but it isn't that accurate. Also I get the same orientations although the contours is rotated around 90 degrees.
解析:如果是我,一定会直接使用pca分别求出两个轮廓的角度,然后算差。但是原文中使用了,并且提出了独特的解决方法。
Shape Distance and Common Interfaces
https://docs.opencv.org/3.0-beta/modules/shape/doc/shape_distances.html#shapecontextdistanceextractor
Shape Distance algorithms in OpenCV are derivated from a common interface that allows you toswitch between them in a practical way for solving the same problem with different methods.Thus, all objects that implement shape distance measures inherit theShapeDistanceExtractor interface.
当然,有了这个函数,做轮廓匹配也是非常方便:
http://answers.opencv.org/question/28489/how-to-compare-two-contours-translated-from-one-another/
4、发现opencv的不足
I need a maxEnclosingCircle function
opencv目前是没有最大内接圆函数的(当然它还没有很多函数),但是这个只有研究要一定程度的人才会发现。这里他提问了,我帮助解决下:
#include "stdafx.h"
#include <iostream>
using namespace std;
using namespace cv;
VP FindBigestContour(Mat src){
int imax = 0; //代表最大轮廓的序号
int imaxcontour = -1; //代表最大轮廓的大小
std::vector<std::vector<cv::Point>>contours;
findContours(src,contours,CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE);
for (int i=0;i<contours.size();i++){
int itmp = contourArea(contours[i]);//这里采用的是轮廓大小
if (imaxcontour < itmp ){
imax = i;
imaxcontour = itmp;
}
}
return contours[imax];
}
int main(int argc, char* argv[])
{
Mat src = imread("e:/template/cloud.png");
Mat temp;
cvtColor(src,temp,COLOR_BGR2GRAY);
threshold(temp,temp,100,255,THRESH_OTSU);
imshow("src",temp);
//寻找最大轮廓
VP VPResult = FindBigestContour(temp);
//寻找最大内切圆
int dist = 0;
int maxdist = 0;
Point center;
for(int i=0;i<src.cols;i++)
{
for(int j=0;j<src.rows;j++)
{
dist = pointPolygonTest(VPResult,cv::Point(i,j),true);
if(dist>maxdist)
{
maxdist=dist;
center=cv::Point(i,j);
}
}
}
//绘制结果
circle(src,center,maxdist,Scalar(0,0,255));
imshow("dst",src);
waitKey();
}
另过程中,发现了pyimagesearch上的一些不错文章,感谢这个blog的作者的长期、高质量的付出,向他学习。
1、Removing contours from an image using Python and OpenCV
2、Sorting Contours using Python and OpenCV
3、Finding extreme points in contours with OpenCV
https://www.pyimagesearch.com/2016/04/11/finding-extreme-points-in-contours-with-opencv/
结语:
实际上,最近我正在做关于轮廓的事情,这也是今天我做这个研究的直接原因。
我的问题是:如何识别出轮廓准确的长和宽
比如这张,其中2的这个外轮廓明显是识别错误的,这样它的长宽也是错误的(注意里面我标红的1和2)
代码:
int main( int argc, char** argv )
{
//read the image
Mat img = imread("e:/sandbox/leaf.jpg");
Mat bw;
bool dRet;
//resize
pyrDown(img,img);
pyrDown(img,img);
cvtColor(img, bw, COLOR_BGR2GRAY);
//morphology operation
threshold(bw, bw, 150, 255, CV_THRESH_BINARY);
//bitwise_not(bw,bw);
//find and draw contours
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(bw, contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
for (int i = 0;i<contours.size();i++)
{
RotatedRect minRect = minAreaRect( Mat(contours[i]) );
Point2f rect_points[4];
minRect.points( rect_points );
for( int j = 0; j < 4; j++ )
line( img, rect_points[j], rect_points[(j+1)%4],Scalar(255,255,0),2);
}
imshow("img",img);
waitKey();
return 0;
}
我们要得到这样的结果
当然,这个代码我已经差不多写出来了,如何获得轮廓的真实的长宽?这个问题很实际,opencv没有实现,目前看来answeropencv也人问?
就是这张图片?想看看大家的想法。也可以直接在answeropencv上进行讨论。
answerOpencv的讨论地址为:
感谢阅读至此,希望有所帮助。
answerOpenCV轮廓类问题解析的更多相关文章
- 如何利用.Net内置类,解析未知复杂Json对象
如何利用.Net内置类,解析未知复杂Json对象 如果你乐意,当然可以使用强大的第三方类库Json.Net中的JObject类解析复杂Json字串 . 我不太希望引入第三方类库,所以在.Net内置类J ...
- Java 8 Optional 类深度解析
Java 8 Optional 类深度解析 身为一名Java程序员,大家可能都有这样的经历:调用一个方法得到了返回值却不能直接将返回值作为参数去调用别的方法.我们首先要判断这个返回值是否为null,只 ...
- javap -- Java 类文件解析器
参考文档 http://blog.chinaunix.net/uid-692788-id-2681132.html http://docs.oracle.com/javase/7/docs/techn ...
- 解析HTML文件 - 运用SgmlReader类来解析HTML文件
运用.NET Framework类来解析HTML文件.读取数据并不是最容易的.虽然你可以用.NET Framework中的许多类(如StreamReader)来逐行解析文件,但XmlReader提供的 ...
- Java File类基础解析 1
Java File类基础解析 1 File类的构造方法 public File(String pathname) :通过给定的路径名字符转换为抽象路径名来创建新的File实例 String path ...
- 第一个OC类、解析第一个OC程序
01第一个OC 类 本文目录 • 一.语法简介 • 二.用Xcode创建第一个OC的类 • 三.第一个类的代码解析 • 四.添加成员变量 • 五.添加方法 • 六.跟Java的比较 • 七.创建对象 ...
- Spring mybatis源码篇章-NodeHandler实现类具体解析保存Dynamic sql节点信息
前言:通过阅读源码对实现机制进行了解有利于陶冶情操,承接前文Spring mybatis源码篇章-XMLLanguageDriver解析sql包装为SqlSource SqlNode接口类 publi ...
- ParseCrontab类,解析时间规则
<?php /** * Created by PhpStorm. * User: ClownFish 187231450@qq.com * Date: 14-12-27 * Time: 上午11 ...
- Django View类的解析
class View(object): """ Intentionally simple parent class for all views. Only impleme ...
随机推荐
- iOS UI进阶-5.0 蓝牙/加速计/传感器
传感器 实现代码: #import "ViewController.h" @interface ViewController () @end @implementation Vie ...
- 关于原始input的一些事情
1.关于input type为number时 maxlength失效 <input class="myfrom-input" type="text" id ...
- 从0开始搭建vue+webpack脚手架(二)
接着从0开始搭建vue+webpack脚手架(一) 三.配置webpack-dev-server 1. webpack-dev-server自带一个node的服务器, 项目在服务端运行的同时可以实现热 ...
- git 开发中的总结
一.git是什么 1.git是一种分布式的版本管理系统, 分布式相比于集中式的最大区别在于开发者可以提交到本地,每个开发者通过克隆(git clone),在本地机器上拷贝一个完整的Git仓库. 二.g ...
- python中使用rabbitmq消息中间件
上周一直在研究zeromq,并且也实现了了zeromq在python和ruby之间的通信,但是如果是一个大型的企业级应用,对消息中间件的要求比较高,比如消息的持久化机制以及系统崩溃恢复等等需求,这个时 ...
- Chess (SG + 状态压缩预处理)
#include<bits/stdc++.h> #define bit(t) (1 << t) using namespace std; <<; ;//k是集合s的 ...
- 线程&进程
扯淡的yuan 并发&并行 并发:是指系统具有处理多个任务(动作)的能力. 并行:是指系统具有 同时 处理多个任务(动作)的能力. 同步&异步 同步:当进程执行到一个IO(等待外部数据 ...
- importlib
Python提供了importlib包作为标准库的一部分.目的就是提供Python中import语句的实现(以及__import__函数).另外,importlib允许程序员创建他们自定义的对象,可用 ...
- Python print 中间换行 直接加‘\n’
- Locust 设置响应断言
转:http://www.testclass.net/locust/assert/ 性能测试也需要设置断言么? 某些情况下是需要,比如你在请求一个页面时,就可以通过状态来判断返回的 HTTP 状态码是 ...
boundingRect to find the dimensions, but some of the masks I have split in between them so the boundingRect method fails. Can someone suggest me a robust method to find the length of the object in the given mask

erode(bw,bw,Mat(11,11,CV_8UC1));




Shape Distance and Common Interfaces

I need a maxEnclosingCircle function

#include <iostream>
using namespace std;
using namespace cv;
VP FindBigestContour(Mat src){
int imax = 0; //代表最大轮廓的序号
int imaxcontour = -1; //代表最大轮廓的大小
std::vector<std::vector<cv::Point>>contours;
findContours(src,contours,CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE);
for (int i=0;i<contours.size();i++){
int itmp = contourArea(contours[i]);//这里采用的是轮廓大小
if (imaxcontour < itmp ){
imax = i;
imaxcontour = itmp;
}
}
return contours[imax];
}
int main(int argc, char* argv[])
{
Mat src = imread("e:/template/cloud.png");
Mat temp;
cvtColor(src,temp,COLOR_BGR2GRAY);
threshold(temp,temp,100,255,THRESH_OTSU);
imshow("src",temp);
//寻找最大轮廓
VP VPResult = FindBigestContour(temp);
//寻找最大内切圆
int dist = 0;
int maxdist = 0;
Point center;
for(int i=0;i<src.cols;i++)
{
for(int j=0;j<src.rows;j++)
{
dist = pointPolygonTest(VPResult,cv::Point(i,j),true);
if(dist>maxdist)
{
maxdist=dist;
center=cv::Point(i,j);
}
}
}
//绘制结果
circle(src,center,maxdist,Scalar(0,0,255));
imshow("dst",src);
waitKey();
}



answerOpenCV轮廓类问题解析的更多相关文章
- 如何利用.Net内置类,解析未知复杂Json对象
如何利用.Net内置类,解析未知复杂Json对象 如果你乐意,当然可以使用强大的第三方类库Json.Net中的JObject类解析复杂Json字串 . 我不太希望引入第三方类库,所以在.Net内置类J ...
- Java 8 Optional 类深度解析
Java 8 Optional 类深度解析 身为一名Java程序员,大家可能都有这样的经历:调用一个方法得到了返回值却不能直接将返回值作为参数去调用别的方法.我们首先要判断这个返回值是否为null,只 ...
- javap -- Java 类文件解析器
参考文档 http://blog.chinaunix.net/uid-692788-id-2681132.html http://docs.oracle.com/javase/7/docs/techn ...
- 解析HTML文件 - 运用SgmlReader类来解析HTML文件
运用.NET Framework类来解析HTML文件.读取数据并不是最容易的.虽然你可以用.NET Framework中的许多类(如StreamReader)来逐行解析文件,但XmlReader提供的 ...
- Java File类基础解析 1
Java File类基础解析 1 File类的构造方法 public File(String pathname) :通过给定的路径名字符转换为抽象路径名来创建新的File实例 String path ...
- 第一个OC类、解析第一个OC程序
01第一个OC 类 本文目录 • 一.语法简介 • 二.用Xcode创建第一个OC的类 • 三.第一个类的代码解析 • 四.添加成员变量 • 五.添加方法 • 六.跟Java的比较 • 七.创建对象 ...
- Spring mybatis源码篇章-NodeHandler实现类具体解析保存Dynamic sql节点信息
前言:通过阅读源码对实现机制进行了解有利于陶冶情操,承接前文Spring mybatis源码篇章-XMLLanguageDriver解析sql包装为SqlSource SqlNode接口类 publi ...
- ParseCrontab类,解析时间规则
<?php /** * Created by PhpStorm. * User: ClownFish 187231450@qq.com * Date: 14-12-27 * Time: 上午11 ...
- Django View类的解析
class View(object): """ Intentionally simple parent class for all views. Only impleme ...
随机推荐
- iOS UI进阶-5.0 蓝牙/加速计/传感器
传感器 实现代码: #import "ViewController.h" @interface ViewController () @end @implementation Vie ...
- 关于原始input的一些事情
1.关于input type为number时 maxlength失效 <input class="myfrom-input" type="text" id ...
- 从0开始搭建vue+webpack脚手架(二)
接着从0开始搭建vue+webpack脚手架(一) 三.配置webpack-dev-server 1. webpack-dev-server自带一个node的服务器, 项目在服务端运行的同时可以实现热 ...
- git 开发中的总结
一.git是什么 1.git是一种分布式的版本管理系统, 分布式相比于集中式的最大区别在于开发者可以提交到本地,每个开发者通过克隆(git clone),在本地机器上拷贝一个完整的Git仓库. 二.g ...
- python中使用rabbitmq消息中间件
上周一直在研究zeromq,并且也实现了了zeromq在python和ruby之间的通信,但是如果是一个大型的企业级应用,对消息中间件的要求比较高,比如消息的持久化机制以及系统崩溃恢复等等需求,这个时 ...
- Chess (SG + 状态压缩预处理)
#include<bits/stdc++.h> #define bit(t) (1 << t) using namespace std; <<; ;//k是集合s的 ...
- 线程&进程
扯淡的yuan 并发&并行 并发:是指系统具有处理多个任务(动作)的能力. 并行:是指系统具有 同时 处理多个任务(动作)的能力. 同步&异步 同步:当进程执行到一个IO(等待外部数据 ...
- importlib
Python提供了importlib包作为标准库的一部分.目的就是提供Python中import语句的实现(以及__import__函数).另外,importlib允许程序员创建他们自定义的对象,可用 ...
- Python print 中间换行 直接加‘\n’
- Locust 设置响应断言
转:http://www.testclass.net/locust/assert/ 性能测试也需要设置断言么? 某些情况下是需要,比如你在请求一个页面时,就可以通过状态来判断返回的 HTTP 状态码是 ...