开发者社区> 禾路> 正文

寻找复杂背景下物体的轮廓(OpenCV / C++ - Filling holes)

简介: 一、问题提出 这是一个来自"answerOpenCV"(http://answers.opencv.org/question/200422/opencv-c-filling-holes/)整编如下: title:OpenCV / C++ - Filling holes content: H...
+关注继续查看
一、问题提出

这是一个来自"answerOpenCV"(http://answers.opencv.org/question/200422/opencv-c-filling-holes/)整编如下:

title:OpenCV / C++ - Filling holes

content:

Hello there,

For a personnel projet, I'm trying to detect object and there shadow. These are the result I have for now: Original: 

题,原始问题

Object: 

Shadow: 

The external contours of the object are quite good, but as you can see, my object is not full. Same for the shadow. I would like to get full contours, filled, for the object and its shadow, and I don't know how to get better than this (I juste use "dilate" for the moment). Does someone knows a way to obtain a better result please? Regards.

二、问题分析

从原始图片上来看,这张图片的拍摄的背景比较复杂,此外光照也存在偏光现象;而提问者虽然提出的是“将缝隙合并”的要求,实际上他还是想得到目标物体的准确轮廓。

三、问题解决

基于现有经验,和OpenCV,GOCVhelper等工具,能够很快得出以下结果

h通道:

去光差:

阈值:

标注:

 
四、算法关键

这套算法首先解决了这个问题,而且我认为也是稳健鲁棒的。其中,算法中除了经典的“hsv分解->ostu阈值->最大轮廓标注”外,最为关键的算法为顶帽去光差。这个算法来自于冈萨雷斯《数字图像处理教程》形态学篇章,完全按照书本建议实现,体现良好作用。

//answerOpenCV OpenCV / C++ - Filling holes
#include "stdafx.h"
#include <iostream>
#include <vector>
 
 
using namespace cv;
using namespace std;
 
//find the biggest contour
vector<PointFindBigestContour(Mat src){    
    int imax = 0;  
    int imaxcontour = -1;  
    std::vector<std::vector<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];
}
 
//remove Light difference by using top hat
Mat moveLightDiff(Mat src,int radius){
    Mat dst;
    Mat srcclone = src.clone();
    Mat mask = Mat::zeros(radius*2,radius*2,CV_8U);
    circle(mask,Point(radius,radius),radius,Scalar(255),-1);
    //top hat
    erode(srcclone,srcclone,mask);
    dilate(srcclone,srcclone,mask);
    dst =  src - srcclone;
    return dst;
}
 
int mainvoid )
{
    Mat src = imread("e:/sandbox/question.png");
    Mat src_hsv;
    Mat bin;
    Mat src_h;
 
    cvtColor(src,src_hsv,COLOR_BGR2HSV);
    vector<Matrgb_planes;
    split(src_hsvrgb_planes );
    src_h = rgb_planes[0]; // h channel is useful
 
    src_h = moveLightDiff(src_h,40);
    threshold(src_h,bin,100,255,THRESH_OTSU);
 
    //find and draw the biggest contour
    vector<Pointbigestcontrour =  FindBigestContour(bin);
    vector<vector<Point> > controus;
    controus.push_back(bigestcontrour);
    cv::drawContours(src,controus,0,Scalar(0,0,255),3);
    
    waitKey();
    return 0;

}

五、经验小结

解决这个问题我只用了10分钟的时间,写博客10分钟。能够快速解决问题并书写出来的关键为:

1、积累维护的代码库:GOCVHelper(https://github.com/jsxyhelu/GOCvHelper)

2、不断阅读思考实践的习惯;

感谢阅读至此,希望有所帮助!

目前方向:图像拼接融合、图像识别 联系方式:jsxyhelu@foxmail.com

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
18075 0
如何设置阿里云服务器安全组?阿里云安全组规则详细解说
阿里云安全组设置详细图文教程(收藏起来) 阿里云服务器安全组设置规则分享,阿里云服务器安全组如何放行端口设置教程。阿里云会要求客户设置安全组,如果不设置,阿里云会指定默认的安全组。那么,这个安全组是什么呢?顾名思义,就是为了服务器安全设置的。安全组其实就是一个虚拟的防火墙,可以让用户从端口、IP的维度来筛选对应服务器的访问者,从而形成一个云上的安全域。
15501 0
windows server 2008阿里云ECS服务器安全设置
最近我们Sinesafe安全公司在为客户使用阿里云ecs服务器做安全的过程中,发现服务器基础安全性都没有做。为了为站长们提供更加有效的安全基础解决方案,我们Sinesafe将对阿里云服务器win2008 系统进行基础安全部署实战过程! 比较重要的几部分 1.
11330 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
23594 0
腾讯云服务器 设置ngxin + fastdfs +tomcat 开机自启动
在tomcat中新建一个可以启动的 .sh 脚本文件 /usr/local/tomcat7/bin/ export JAVA_HOME=/usr/local/java/jdk7 export PATH=$JAVA_HOME/bin/:$PATH export CLASSPATH=.
12014 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,云吞铺子总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系统盘、创建快照、配置安全组等操作如何登录ECS云服务器控制台? 1、先登录到阿里云ECS服务器控制台 2、点击顶部的“控制台” 3、通过左侧栏,切换到“云服务器ECS”即可,如下图所示 通过ECS控制台的远程连接来登录到云服务器 阿里云ECS云服务器自带远程连接功能,使用该功能可以登录到云服务器,简单且方便,如下图:点击“远程连接”,第一次连接会自动生成6位数字密码,输入密码即可登录到云服务器上。
31880 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
13779 0
+关注
禾路
图像处理工程师,专注图像处理多年,长期奋斗在图像增强、识别一线。实战经验丰富,研究开发的连铸体拼接算法、人脸美化算法、红外线血管增强识别系统、中药识别系统、石材大板识别系统等均已投入使用。对opencv有着深入理解和解析,以jsxyhelu账号参与OpenCV项目。
270
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
OceanBase 入门到实战教程
立即下载
阿里云图数据库GDB,加速开启“图智”未来.ppt
立即下载
实时数仓Hologres技术实战一本通2.0版(下)
立即下载