使用 C++ FindContours 在视频图像中查找轮廓的问题

2024-01-03

我现在正在工作的程序是almost完成了,但我对结果不是很满意。通过使用 Canny 算法,我成功地获得了非常清晰的物体轮廓,但程序在识别轮廓并用红线绘制轮廓时存在一些问题。该程序:

void setwindowSettings(){
    namedWindow("Contours", CV_WINDOW_AUTOSIZE);

    createTrackbar("LowerC", "Contours", &lowerC, 255, NULL);
    createTrackbar("UpperC", "Contours", &upperC, 255, NULL);
}

void wait(void)
{
    long t=30000000;
    while(t--);
}

int main(void)
{
VideoCapture cap(0); // open the default camera
if(!cap.isOpened())  // check if we succeeded
    return -1;

Mat frame,foreground,image;
double pt1, pt2, area;
Rect rect;
int i;

vector<vector<Point> > contours;
vector<vector<Point> > largest_contours;

namedWindow("Capture", CV_WINDOW_AUTOSIZE);
setwindowSettings();

while(1){
    cap >> frame; // get a new frame from camera
    if( frame.empty() )
            break;
    image=frame.clone();

    cvtColor(image,foreground,CV_BGR2GRAY);
    GaussianBlur(foreground,foreground,Size(9,11),0,0);
    Canny(foreground,foreground,lowerC,upperC,3);

    findContours(foreground,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE);  

    if(contours.empty())
        continue;

    double largest_area = 0;

    for( i= 0; i < contours.size(); i++){  // get the largest contour
        area = fabs(contourArea(contours[i]));
        if(area >= largest_area){
            largest_area = area;
            largest_contours.clear(); 
            largest_contours.push_back(contours[i]);
        }
    }

    if(largest_area>=3000){   // draw the largest contour if exceeded minimum largest area 
        drawContours(image,largest_contours,-1,Scalar(0,0,255),2);
        printf("area = %.f\n",largest_area);
    }

    wait();

    imshow( "Capture",image );
    imshow("Contours",foreground);

    if(waitKey(30) >= 0) break;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}

方案概要:

  1. 从相机获取图像
  2. 噪声过滤(转换为灰色→模糊→Canny)
  3. 寻找轮廓
  4. 找到图像中最大的轮廓及其面积,即对象
  5. 在物体周围画一条红线并打印出最大面积
  6. 冲洗并重复

结果:

我很少得到我想要的东西;检测到轮廓,绘制红线(GOOD ONE):

...通常我都会得到这个;未检测到轮廓,不是红线(BAD ONE):

有机会获得GOOD ONE关于1/20这不太好。另外,物体的轮廓线Contours当物体周围出现红线时,屏幕会闪烁(参见“GOOD ONE”图片)。 我正在使用我的一个对象(一个小黑色方框)来回答这个问题,但请注意,该对象检测程序的主要目标是检测物体,无论其形状或颜色如何。

所以我的问题是:

  1. 尽管轮廓清晰如日,为什么我还是得到了坏的?
  2. 谁能分享关于如何改进轮廓检测的更好想法? (即更好的模糊算法)
  3. 当在物体周围绘制红线时,如何避免轮廓线闪烁?

  1. 由于您正在使用最大轮廓的事实,所以我假设您正在尝试检测相机视野中出现的最大物体。我想知道为什么右上角的窗光/明亮光源不会创建任何轮廓(可能是由于模糊)。您可以存储背景图像并从出现对象的图像中减去它。通过这种方式,您可以导出对象。您可以在差异图像中应用轮廓查找。absdiff(frame_now,frame_backgrnd,diff) where diff是差异图像。
  2. 如果物体处于运动状态并且您想要检测,您可以使用光流结合最大轮廓来检测物体。
  3. 尝试在不使用模糊功能的情况下进行处理,然后检测最大的轮廓区域。
  4. 为了绘制点尝试这个

    for(int i = 1;i<(int)largest_contours[0].size();i++)
         line(image,largest_contours[0][i-1],largest_contours[0][i],cv::Scalar(0,0,255),2,8,0);
    
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 C++ FindContours 在视频图像中查找轮廓的问题 的相关文章

随机推荐

  • Spark:将 RDD 结果写入文件系统很慢

    我正在使用 Scala 开发 Spark 应用程序 我的应用程序仅包含一项需要改组的操作 即cogroup 它在合理的时间完美运行 我面临的问题是当我想将结果写回文件系统时 由于某种原因 它比运行实际程序花费的时间更长 起初 我尝试在不重新
  • 检查正在运行的程序中是否存在内存泄漏

    出于好奇 我有一个关于检查内存泄漏的问题 作为一个用过的人valgrind在过去的一两年里 我经常检查代码中的内存泄漏 我突然想到它只检测丢失 未释放的内存来世之后的程序 因此 鉴于此 我在想如果你有一个长期运行的程序malloc 是间歇性
  • C 中允许重复的 const 限定符,但 C++ 中不允许?

    示例代码片段 const const const int x 10 int main 在 C 中编译 但在 C 中不编译 为什么用C编译 我认为这在 C 中也会失败 没关系 C 标准的哪一部分禁止使用重复项constC 标准的哪一部分允许这
  • 如何对 fgets 使用 feof 和ferror(C 中的 minishell)[重复]

    这个问题在这里已经有答案了 我已经编写了这个 minishell 但我不确定我是否对错误进行了正确的控制 我知道 fgets 可以返回 feof 和ferror http www manpagez com man 3 fgets http
  • spring事务超时可配置

    我有一个具有固定超时的事务方法 有没有一种方法可以通过即配置来配置事务超时application yml Transactional propagation Propagation REQUIRED timeout TIMEOUT publ
  • 如何使用 Snowflake SQL 解析 ISO 8601 时间戳?

    我正在寻找一个允许我解析 ISO8601 时间戳的通用函数 我知道关于to timestamp tz https docs snowflake net manuals sql reference functions to timestamp
  • 将两个整数合并为一个并稍后解码

    使用 C 我需要将两个不同的 ID 组合成一个 16 位整数 然后我需要将这个 16 位整数解码为两个原始 ID 值 Example Store two integers into one unsigned short Identifier
  • 测试:如何测试视图包含所需的数据

    假设厨师可以制作食谱 副厨师可以创建必须经过主厨批准的食谱 您想要测试一下 当主厨查看她的主页时 她会看到她自己创建的食谱 您还想测试她是否看到有食谱等待她的批准 我可以想到两种方法来做到这一点 测试视图是否包含某些单词 例如 您的食谱 和
  • 当我使用与 SeismicXML 示例相同的 NSXMLParser 时出现内存泄漏问题

    我已经完成了与 SeismicXML 示例相同的 xml 解析 但现在它给了我内存泄漏问题 当我用仪器测试 SeismicXML 时 它也给出了相同的内存泄漏 在SeismicXML中 有EarthQuake示例 它包含来自xml解析的所有
  • String.find 始终返回 true (C++)

    我试图让布尔型found word 在找到单词 字符时返回 true 如果没有找到则返回 false 但无论我在文本中写什么 它总是返回 true 循环本身有效 已经尝试过了 包括 IOStream 和字符串 while timestoru
  • 河内塔 - 用 Python 解决中途算法

    河内塔有可能中途解决吗 我已经做了广泛的研究来寻找可以半途解决用户配置的代码 但我还没有找到 这是一项作业 我需要代码从用户停止解决的地方接管并继续为用户解决它 而不将谜题重置为一 我知道有现成的递归算法 但这不是我正在寻找的 我正在寻找可
  • [if ( ! Defined( 'ABSPATH' ) )] 是什么意思

    我目前正在从头开始构建一个 WordPress 主题 作为 在工作中学习 的一种手段 尽管我过去非常依赖 PageBuilders 但我对后端工作有一定的经验 我现在希望创建一个没有任何页面构建器的主题 作为提高其加载速度等的方法 目前 我
  • C# 中重载函数调用运算符

    是否可以重载 C 中的默认函数运算符 运算符 如果是这样 怎么办 如果没有 是否有解决方法可以产生类似的效果 EDIT 我试图给一个类一个默认运算符 大致如下 class A A int myvalue save value public
  • 使用警报管理器与 ScheduledExecutorService 调度相同的任务有什么区别

    您好 我在互联网上读到 我们可以使用警报管理器安排我们想要以一定间隔运行的任何事情 并且ScheduledExecutorService 我想知道它们之间有什么区别以及什么时候使用 提前致谢 ScheduledExecutorService
  • git-mv 的目的是什么?

    据我了解 Git 并不真正需要跟踪file重命名 移动 复制操作 那么真正的目的是什么 的git mv https git scm com docs git mv 手册页没有特别描述性 它已经过时了吗 它是一个内部命令 不适合普通用户使用吗
  • NUnit TestCaseSource 将值传递给工厂

    我正在使用 NUnit 2 5 3 TestCaseSource 属性并创建一个工厂来生成我的测试 像这样的东西 Test TestCaseSource typeof TestCaseFactories VariableString pub
  • 方案/球拍过滤器/映射多个参数

    可以说我想做以下事情 define foo lst x filter function lst but function接受 2 个参数 并且function给了我 其中之一是清单lst它将使用 另一个是x 从语法上讲 我将如何更改该行以传
  • 在 UNIX shell 脚本中将十进制转换为十六进制

    在 UNIX shell 脚本中 我可以使用什么将十进制数转换为十六进制数 我以为 od 可以解决这个问题 但它没有意识到我正在向它提供数字的 ASCII 表示形式 打印 总的 目前可以使用 但是还有什么可用的呢 Tried printf
  • 如何从单词中删除字母 X?

    我需要从单词中删除字母 X 例如 我需要剪掉 Star Wars 中的第一个字母 munich 中的第四个字母 1 star wars 4 munich 5 casino royale 7 the fast and the furious
  • 使用 C++ FindContours 在视频图像中查找轮廓的问题

    我现在正在工作的程序是almost完成了 但我对结果不是很满意 通过使用 Canny 算法 我成功地获得了非常清晰的物体轮廓 但程序在识别轮廓并用红线绘制轮廓时存在一些问题 该程序 void setwindowSettings namedW