在opencv中发现凸性缺陷? [根据给定的输入图像崩溃..]

2024-05-04

我有一个计算图像凸包的程序。我正在尝试使用此信息来计算fingers存在于输入图像中。从一些冲浪中我发现做到这一点的方法(数手指)是

  1. 寻找轮廓
  2. 凸包
  3. 凸性缺陷

但我在使用凸性缺陷函数时遇到了麻烦。它编译得很好,但在运行时程序会因某些输入图像而崩溃,但不会因其他输入图像而崩溃,我似乎无法弄清楚为什么。

这些是输入图像

  1. this http://i50.tinypic.com/28mps1k.jpg图像导致崩溃
  2. but this http://i46.tinypic.com/x1dlvq.jpg才不是。
  3. this http://i50.tinypic.com/15q6sdi.jpg即使它与上面类似,也会导致崩溃

code..

#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <opencv/cxcore.h>
#include <stdio.h>

#define CVX_RED     CV_RGB(0xff,0x00,0x00)
#define CVX_GREEN   CV_RGB(0x00,0xff,0x00)
#define CVX_BLUE    CV_RGB(0x00,0x00,0xff)

int main(int argc, char* argv[]) {

  cvNamedWindow( "original", 1 );
  cvNamedWindow( "contours", 1 );
  cvNamedWindow( "hull", 1 );
  IplImage* original_img = NULL;

  original_img = cvLoadImage("img.jpg", CV_LOAD_IMAGE_GRAYSCALE );

  IplImage* img_edge = cvCreateImage( cvGetSize(original_img), 8, 1 );
  IplImage* contour_img = cvCreateImage( cvGetSize(original_img), 8, 3 );
  IplImage* hull_img = cvCreateImage( cvGetSize(original_img), 8, 3 );

  cvThreshold( original_img, img_edge, 128, 255, CV_THRESH_BINARY );

  CvMemStorage* storage = cvCreateMemStorage();
  CvSeq* first_contour = NULL;

  int Nc = cvFindContours(
     img_edge,
     storage,
     &first_contour,
     sizeof(CvContour),
     CV_RETR_LIST // Try all four values and see what happens
  );

  for( CvSeq* c=first_contour; c!=NULL; c=c->h_next ) {
     cvCvtColor( original_img, contour_img, CV_GRAY2BGR );
     cvDrawContours(
        contour_img,
        c,
        CVX_RED,  
        CVX_BLUE,
        0,     
        2,
        8
     );
  }

  //----------------------------------------------------------------------Convex Hull

  CvMemStorage* hull_storage = cvCreateMemStorage();
  CvSeq* retHulls = NULL;

  for(CvSeq* i = first_contour; i != NULL; i = i->h_next){
    retHulls = cvConvexHull2(i,hull_storage,CV_CLOCKWISE,0); 
    // with 1 it draws the Hull image but not with 0..?
    // however it needs to be 0 for convexitydefects to work?
  }

  printf(" %d elements:\n", retHulls->total );

  // drawing hull

  for( CvSeq* j=retHulls; j!=NULL; j=j->h_next ) {
    cvCvtColor( original_img, hull_img, CV_GRAY2BGR );
    cvDrawContours(
        hull_img,
        j,
        CVX_RED,  
        CVX_BLUE,
        0,        
        2,
        8
     );  

  }


  //----------------------------------------------------------------------Convexity Defects??

  CvMemStorage* convexStorage = cvCreateMemStorage();
  CvSeq* defect = NULL;
  defect = cvConvexityDefects(first_contour,retHulls, convexStorage);
  printf(" %d defect:\n", defect->total );


  cvShowImage( "contours", contour_img );
  cvShowImage( "original", original_img );
  cvShowImage( "hull", hull_img );
  cvWaitKey(0);
  cvDestroyWindow( "contours" );
  cvDestroyWindow( "original" );
  cvDestroyWindow( "hull" );
  cvReleaseImage( &original_img );
  cvReleaseImage( &contour_img );
  cvReleaseImage( &hull_img );
  cvReleaseImage( &img_edge );
  return 0;
}

cvConvexityDefects期望convexHull序列(第二个参数)包含索引contour序列(第一个参数):

使用 ConvexHull2 获得的凸包应包含轮廓点的指针或索引,而不是包点本身

  1. 在最简单的情况下,cvFindContours返回一个简单的轮廓(您的第二张图像),您很幸运,您的代码将提供正确的序列作为第一个参数。

  2. In case cvFindContours找到轮廓中的孔(您的第三张图像),或者如果有几个简单的轮廓或带孔的轮廓(您的第一张图像),您的代码:

    1. 依次找到每个轮廓的凸包,但只记住最后一个(因为循环的每次迭代都会覆盖retHulls多变的)

    2. 传递轮廓的整个层次结构,它与中的索引不对应retHulls, to cvConvexityDefects作为第一个参数。

相反,您应该:

  1. passed CV_RETR_EXTERNAL to the cvFindContour仅获得外部轮廓(您不关心孔的缺陷)

  2. 移动了cvConvexityDefects在最后一个循环内。

就像是:

  /* ... */

  if (argc < 2) {
      std::cerr << "Usage: convexity IMAGE\n";
      exit(1);
  }

  cvNamedWindow( "original", 1 );
  cvNamedWindow( "contours", 1 );
  cvNamedWindow( "hull", 1 );
  IplImage* original_img = NULL;

  original_img = cvLoadImage(argv[1], CV_LOAD_IMAGE_GRAYSCALE );

  IplImage* img_edge = cvCreateImage( cvGetSize(original_img), 8, 1 );
  IplImage* contour_img = cvCreateImage( cvGetSize(original_img), 8, 3 );
  IplImage* hull_img = cvCreateImage( cvGetSize(original_img), 8, 3 );

  cvThreshold( original_img, img_edge, 128, 255, CV_THRESH_BINARY );

  CvMemStorage* storage = cvCreateMemStorage();
  CvSeq* first_contour = NULL;

  int Nc = cvFindContours(
     img_edge,
     storage,
     &first_contour,
     sizeof(CvContour),
     CV_RETR_EXTERNAL // Try all four values and see what happens
  );

  cvCvtColor( original_img, contour_img, CV_GRAY2BGR );
  for( CvSeq* c=first_contour; c!=NULL; c=c->h_next ) {
     cvDrawContours(
        contour_img,
        c,
        CVX_RED,
        CVX_BLUE,
        0,
        2,
        8
     );
  }
  cvShowImage( "contours", contour_img );

  //----------------------------------------------------------------------Convex Hull
  //-------------------------------------------------------------------Convex Defects

  CvMemStorage* hull_storage = cvCreateMemStorage();
  CvSeq* retHulls = NULL;

  cvCvtColor( original_img, hull_img, CV_GRAY2BGR );
  for(CvSeq* i = first_contour; i != NULL; i = i->h_next){
    retHulls = cvConvexHull2(i,hull_storage,CV_CLOCKWISE,0);
    printf(" %d elements:\n", retHulls->total );

    CvSeq* defect = NULL;
    defect = cvConvexityDefects(i,retHulls, NULL); // reuse storage of the contour
    printf(" %d defect:\n", defect->total );

    // drawing hull.... you can't use the one returned above since it only
    // contains indices
    retHulls = cvConvexHull2(i,hull_storage,CV_CLOCKWISE,1);
    cvDrawContours(
        hull_img,
        retHulls,
        CVX_RED,
        CVX_BLUE,
        0,
        2,
        8
     );
  }

  cvShowImage( "hull", hull_img );
  /* ... */
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在opencv中发现凸性缺陷? [根据给定的输入图像崩溃..] 的相关文章

  • 添加 Nullable int 时保持 null?

    我想添加可为空的int 并保留null当所有值都是null 我想要这个结果 1 2 3 1 null 1 null null null O null 0 问题是 如果我将一个值与 null 相加 结果为 null int i1 1 int
  • 在 OnModelCreating 期间设置列名称

    Issue 我目前正在尝试通过设置的属性为我的表及其列添加前缀 我正在使用实体框架核心 我已经正确地为表名添加了前缀 但我似乎无法弄清楚列的前缀 我有一种感觉 我需要使用反射 我已经留下了我的 可能很糟糕的 反思尝试 有人有办法在实体中设置
  • C++ 长 switch 语句还是用地图查找?

    在我的 C 应用程序中 我有一些值充当代表其他值的代码 为了翻译代码 我一直在争论使用 switch 语句还是 stl 映射 开关看起来像这样 int code int value switch code case 1 value 10 b
  • 删除是如何工作的? [复制]

    这个问题在这里已经有答案了 可能的重复 C 编程 free 如何知道要释放多少 https stackoverflow com questions 1518711 c programming how does free know how m
  • 检测wlan是否关闭

    任何人都可以给我一个提示 如何在 Windows Phone 上以编程方式检测 C 8 1 应用程序 不是 8 0 是否启用 禁用 WLAN 我不想更改这些设置 只是需要知道 该解决方案是一个 Windows 8 1 通用应用程序 Wind
  • linq 中使用字符串数组 c# 的 'orderby'

    假设我有一个这样的方法定义 public CustomerOrderData GetCustomerOrderData string CustomerIDs var query from a in db Customer join b in
  • 运行需要 MySql.Data 的内置 .NET 应用程序

    我在运行我编写的内置 NET 应用程序时遇到问题 我的应用程序使用最新的 MySql 连接器 该连接器安装在我的系统上 当我尝试将其添加为引用时 该连接器显示为 NET 4 Framwork 组件 当我在环境中以调试模式运行应用程序时 一切
  • C# 5 async/await 线程机制感觉不对?

    为什么让调用线程进入异步方法直到内部 等待 一旦调用异步方法就生成一个线程 这不是更干净吗 这样您就可以确定异步方法会立即返回 您不必担心在异步方法的早期阶段没有做任何昂贵的事情 我倾向于知道某个方法是否要在 我的 线程上执行代码 不管是堵
  • 使用查询表达式对 List 进行排序

    我在使用 Linq 订购这样的结构时遇到问题 public class Person public int ID get set public List
  • MFC:如何设置CEdit框的焦点?

    我正在开发我的第一个简单的 MFC 项目 但我正在努力解决一个问题 想要设置所有的焦点CEdit其中一个对话框中的框 我的想法是 当打开对话框时 焦点位于第一个编辑框上 然后使用 选项卡 在它们之间交换 我看到了方法SetFocus 但我无
  • 如何在三个 IEnumerable 上使用 Zip [重复]

    这个问题在这里已经有答案了 可能的重复 使用 Linq 从 3 个集合创建项目 https stackoverflow com questions 5284315 create items from 3 collections using
  • 析构函数中的异步操作

    尝试在类析构函数中运行异步操作失败 这是代码 public class Executor public static void Main var c1 new Class1 c1 DoSomething public class Class
  • 引用/指针失效到底是什么?

    我找不到任何定义指针 引用无效在标准中 我问这个问题是因为我刚刚发现 C 11 禁止字符串的写时复制 COW 据我了解 如果应用了 COW 那么p仍然是一个有效的指针并且r以下命令后的有效参考 std string s abc std st
  • 为什么 Cdecl 调用在“标准”P/Invoke 约定中经常不匹配?

    我正在开发一个相当大的代码库 其中 C 功能是从 C P Invoked 的 我们的代码库中有很多调用 例如 C extern C int stdcall InvokedFunction int 使用相应的 C DllImport CPlu
  • 如何使用 NPOI 按地址(A1、A2)获取 Excel 单元格值

    我有一个 Excel 单元格地址 例如 A1 A2 如何使用 C 中的 NPOI 框架以编程方式访问此单元格 我找到的一些 Java POI 示例代码 CellReference cr new CellReference A1 row my
  • Project Euler #8,我不明白我哪里出了问题[关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我正在做项目欧拉第八题 https projecteuler net problem 8 其中我得到了这个大得离谱的数字 7316
  • Linux mremap 不释放旧映射?

    我需要一种方法将页面从一个虚拟地址范围复制到另一个虚拟地址范围 而无需实际复制数据 范围很大 延迟很重要 mremap 可以做到这一点 但问题是它也会删除旧的映射 由于我需要在多线程环境中执行此操作 因此我需要旧映射能够同时使用 因此稍后当
  • CUDA 8 编译错误 -std=gnu++11

    我正在尝试转换一些代码以使用 CUDA 并且我认为我遇到了兼容性问题 我们使用CMake 这些是我使用的 gcc 和 CUDA 版本 gcc version gcc Ubuntu 5 4 0 6ubuntu1 16 04 5 5 4 0 2
  • 通过 Tab 键浏览 XML 文档字段

    In VB NET you can move through the fields in the XML member documentation with the Tab key 这在 C 中不起作用 还有其他方法吗 除了用鼠标将光标放在
  • 使用决策树

    我知道 tl dr 我将尝试解释我的问题 而不会用大量蹩脚的代码来打扰您 我正在做一项学校作业 我们有蓝精灵的图片 我们必须通过前景背景分析来找到它们 我有一个 Java 决策树 其中包含所有数据 HSV 直方图 1 一个节点 然后尝试找到

随机推荐

  • 如何以编程方式断开 android 4.1.2 nexus 中的呼叫

    我能够以编程方式断开 Android 2 2 中未知号码来电的呼叫 但在 android 4 1 中 它不起作用 在 android 2 2 中断开通话的工作代码 private Class c private Method m priva
  • next-auth google 提供商无法正常工作,访问被阻止:此应用程序的请求无效

    这整个星 期我都在摸索 我已经尝试了几乎所有的方法 我正在尝试使用 next auth google 提供商 在 GCP 中 在授权网址和重定向网址中 本地主机 3000 真实域名网站 本地主机 3000 api auth callback
  • 如何传递数据到 Laravel 中查看?

    我将数据传递到我的刀片视图return View make blog posts 在我的刀片视图中 我正在尝试运行 foreach posts as post 我最终得到一个错误说 posts没有定义 我的问题是如何 posts数组被调用
  • 升级到Python 3.6后启动时无法启动cloud-init

    我在新的云服务器 Ubuntu 16 04 上安装了 Python 3 6 而不是默认的 3 5 版本 我重启服务器后发现执行失败cloud init启动时出现以下错误syslog Sep 20 16 16 14 cloud init 13
  • 如何阻止浏览器在选项卡之间共享会话?

    How to NOT在多个浏览器选项卡之间共享会话 我在 JSP Servlet 应用程序中使用 Spring Security 我想知道 我们如何使用 Spring Security 实现用户在更改浏览器选项卡时被迫再次登录的行为 免责声
  • Flutter更新Appbar中的文本

    我需要帮助更新应用栏中的文本以匹配我当前所在的页面 因此 如果我在 设置 页面中 那么我需要在 AppBar 文本中显示它 我添加代码和屏幕截图是为了更好地解释我想要实现的目标 主dart void main gt runApp MyApp
  • ant + yuicompressor 路径错误

    我有一个文件C Bin test js我想压缩并重命名测试 min js my ant 构建 xml看起来像这样
  • 在不滚动的情况下对 UITableViewCell 的高度变化进行动画处理

    我知道如何使用此处所示的方法对 UITableViewCell 的高度变化进行动画处理 当 UITableViewCell 被选中时 你能用动画来改变高度吗 https stackoverflow com questions 460014
  • 设置 CMake OBJECT 库的输出目录

    在我的 CMake 文件中 我指定了一个对象库 add library core OBJECT sourcefiles 我在共享库中进一步引用了这组目标文件 add library sharedlib SHARED
  • Passenger 无法识别本地安装的 gem,可使用打包的 gem

    这是一个生产服务器 我已经安装了 Passenger 并且大部分情况下都可以正常工作 然而 我总是必须将宝石与项目打包在一起 如果不这样做 我会收到以下错误消息 Missing the Rails 2 3 8 gem Please gem
  • logback 消息字段可以被截断/修剪为 n 个字符吗?

    有时会看到巨大的日志消息 并且并不总是能够 轻松 自动换行 有没有办法截断 message比如说 80 个字符logback xml 看一下格式修饰符部分 From http logback qos ch manual layouts ht
  • 如何给DArray的元素设置值?

    我正在探索 Julia 的并行计算并尝试了以下方法 a dzeros 5 a 1 5 但刚刚收到此错误 setindex not defined for DArray Float64 1 Array Float64 1 嗯 我以为手册上说s
  • 如何在存储过程中调用存储过程(带2个参数)?

    我有具有相同参数 服务器名称和日期 的存储过程 我想编写一个存储过程并在该 SP 中执行它们 称为 SP All CREATE PROCEDURE dbo SP All AS BEGIN exec sp 1 myDate datetime
  • IEEE-754 32 位(单精度)指数 -126 而不是 -127

    我知道我是否有这样的号码 1 1001 0001 0011 0011 0000 0001 0101 000 1 sign bit 8 bit biased exponent 23 bit fraction mantissa 我可以通过从有偏
  • Math.random 生成多少熵?

    我想生成一个非常大的随机数 我不需要这个号码来保证加密安全 因此 我没有使用crypto getRandomValues https developer mozilla org en US docs Web API RandomSource
  • 处理原始 HTTP 请求内容

    我正在 ASP NET 中做一个电子商务解决方案 它使用PayPal 网站支付标准 https www paypal com IntegrationCenter ic standard home html服务 除此之外 我还使用他们提供的服
  • 使用 Git 和 Eclipse 管理 Android 项目

    我相信我有一个非常常见的问题 它会影响具有多个应用程序版本的开发人员 在我的例子中 我有两个 付费版本和免费版本 为了管理这两个版本 我使用具有 2 个不同分支的同一个 git 项目 免费和付费 然而 我的源代码包名称彼此不同 如预期 并且
  • 如何在neo4j中显示屏幕上的所有节点

    我有近 5000 个节点Recipes和 5 个节点Meal Types在 Neo4j 数据库中 目前他们之间没有任何关系 我正在下面运行 CQL MATCH n RETURN n LIMIT 100000 这运行良好 但它返回与相关的节点
  • 投影 3D 网格的 2D 轮廓算法

    给定 一个 3D 网格 由一组顶点和三角形定义 并用这些点构建网格 问题 找到任意平面上投影的任意旋转网格的二维轮廓 投影很容易 挑战在于找到平面中投影三角形边的 外壳 我需要一些有关研究该算法的输入 指针的帮助 为简单起见 我们可以假设
  • 在opencv中发现凸性缺陷? [根据给定的输入图像崩溃..]

    我有一个计算图像凸包的程序 我正在尝试使用此信息来计算fingers存在于输入图像中 从一些冲浪中我发现做到这一点的方法 数手指 是 寻找轮廓 凸包 凸性缺陷 但我在使用凸性缺陷函数时遇到了麻烦 它编译得很好 但在运行时程序会因某些输入图像