【问题标题】:Opencv 3.0.0 , C++, Visual Studio 2015 - error in finding contours and ConvexHullOpencv 3.0.0、C++、Visual Studio 2015 - 查找轮廓和 ConvexHull 时出错
【发布时间】:2015-11-16 14:00:53
【问题描述】:

我正在尝试编写一个程序,该程序可以在某个对象周围创建一个多边形(任意数量的边)并找到多边形的质心。为此,我选择使用 convexhull 和 findContours 函数。在以下程序中,您将获得两个窗口。一个窗口包含用于更改 HSV 和过滤器形态值的跟踪栏,另一个窗口包含过滤后的图像。过滤图像并获得二值图像后,您必须单击“c”找到轮廓,然后单击“h”找到凸包。过滤图像并执行形态学操作不是问题。主要问题是寻找轮廓。

#include<iostream>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include<opencv2\core\core.hpp>
#include<opencv2\video\background_segm.hpp>
#include<Windows.h>
using namespace cv;
using namespace std;

//functions prototypes
void on_trackbar(int, void*);
void createTrackbars();
void showimgcontours(Mat &threshedimg, Mat &original);
void toggle(int key);
void morphit(Mat &img);
void blurthresh(Mat &img);

//function prototypes ends here

//boolean toggles

bool domorph = false;
bool doblurthresh = false;
bool showchangedframe = false;
bool showcontours = false;
bool showhull = false;

//boolean toggles end


int H_MIN = 0;
int H_MAX = 255;
int S_MIN = 0;
int S_MAX = 255;
int V_MIN = 0;
int V_MAX = 255;

int kerode = 1;
int kdilate = 1;
int kblur = 1;
int threshval = 0;


int main(void)
{
    createTrackbars();
    on_trackbar(0, 0);

    Mat frame, hsvframe, rangeframe;
    int key;
    VideoCapture cap(0);
    while ((key = waitKey(30)) != 27)
    {
        toggle(key);
        cap >> frame;
        flip(frame, frame, 180);
        cvtColor(frame, hsvframe, COLOR_BGR2HSV);

        inRange(hsvframe, Scalar(H_MIN, S_MIN, V_MIN), Scalar(H_MAX, S_MAX,    V_MAX), rangeframe);

        if (domorph)
            morphit(rangeframe);

        if (doblurthresh)
            blurthresh(rangeframe);

        if (showcontours)
            showimgcontours(rangeframe, frame);

        if (showchangedframe)
            imshow("Camera", frame);
        else
            imshow("Camera", rangeframe);

    }

}


void on_trackbar(int, void*)
{//This function gets called whenever a
 // trackbar position is changed
    if (kerode == 0)
        kerode = 1;
    if (kdilate == 0)
        kdilate = 1;
    if (kblur == 0)
        kblur = 1;
}
void createTrackbars()
{
    String trackbarWindowName = "TrackBars";
    namedWindow(trackbarWindowName, WINDOW_NORMAL);
    createTrackbar("H_MIN", trackbarWindowName, &H_MIN, H_MAX, on_trackbar);
    createTrackbar("H_MAX", trackbarWindowName, &H_MAX, H_MAX, on_trackbar);
    createTrackbar("S_MIN", trackbarWindowName, &S_MIN, S_MAX, on_trackbar);
    createTrackbar("S_MAX", trackbarWindowName, &S_MAX, S_MAX, on_trackbar);
    createTrackbar("V_MIN", trackbarWindowName, &V_MIN, V_MAX, on_trackbar);
    createTrackbar("V_MAX", trackbarWindowName, &V_MAX, V_MAX, on_trackbar);
    createTrackbar("Erode", trackbarWindowName, &kerode, 31, on_trackbar);
    createTrackbar("Dilate", trackbarWindowName, &kdilate, 31, on_trackbar);
    createTrackbar("Blur", trackbarWindowName, &kblur, 255, on_trackbar);
    createTrackbar("Thresh", trackbarWindowName, &threshval, 255,    on_trackbar);

}

void morphit(Mat &img)
{
    erode(img, img, getStructuringElement(MORPH_RECT, Size(kerode, kerode)));
    dilate(img, img, getStructuringElement(MORPH_RECT, Size(kdilate, kdilate)));
}
void blurthresh(Mat &img)
{
    //medianBlur(img,img,kblur%2+3+kblur);
    blur(img, img, Size(kblur, kblur), Point(-1, -1), BORDER_DEFAULT);
    threshold(img, img, threshval, 255, THRESH_BINARY_INV);
}
void toggle(int key)
{

    //toggle line start
    if (key == 'm')
        domorph = !domorph;
    if (key == 'b')
        doblurthresh = !doblurthresh;
    if (key == 'r')
        showchangedframe = !showchangedframe;
    if (key == 'c')
        showcontours = !showcontours;
    if (key == 'h')
        showhull = !showhull;
    //toggle line end
}

void showimgcontours(Mat &threshedimg, Mat &original)
{
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    int largest_area = 0;
    int largest_contour_index = 0;

    findContours(threshedimg, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);

    vector<vector<Point> >hull(contours.size());

    //find a hull for each contour
    for (int i = 0; i < contours.size(); i++)
    {
        convexHull(Mat(contours[i]), hull[i], false);
    }

    //this will find the largest contour
    for (int i = 0; i< contours.size(); i++) // iterate through each contour. 
    {
        double a = contourArea(contours[i], false);  //  Find the area of each contour
        if (a>largest_area)
        {
            largest_area = a;
            largest_contour_index = i;                //Store the index of   the largest contour
        }

    }
    //search for the largest contour has end

    if (contours.size() > 0)
    {
        drawContours(original, contours, largest_contour_index, CV_RGB(0, 255, 0), 2, 8, hierarchy);
        //if you want to show every contour, use the following
        //drawContours(original,-1, CV_RGB(0, 255, 0), 2, 8, hierarchy);
        if (showhull)
            drawContours(original, hull, largest_contour_index, CV_RGB(0, 0, 255), 2, 8, hierarchy);
        //if you want to show every hull(s), use the following
        //drawContours(original,-1, CV_RGB(0, 255, 0), 2, 8, hierarchy);
    }
}

问题在于,每当我尝试运行 findcontours() 函数时,它总是会触发向量类模板中的断点(void Tidy() 中的某处)。弹出一个对话框并显示以下消息:

“ConsoleApplication2.exe 中 0x00007FF9374CD328 (ucrtbase.dll) 处出现未处理的异常:将无效参数传递给认为无效参数致命的函数。”

然后对话框将我重定向到向量类模板,并在下面段的第 7 行显示一个断点。

void _Tidy()
    {   // free all storage
    if (this->_Myfirst() != pointer())
        {   // something to free, destroy and deallocate it
        this->_Orphan_all();
        _Destroy(this->_Myfirst(), this->_Mylast());
        this->_Getal().deallocate(this->_Myfirst(),
            this->_Myend() - this->_Myfirst());
        this->_Myfirst() = pointer();
        this->_Mylast() = pointer();
        this->_Myend() = pointer();
        }
    }

这是 findContours 函数或向量类的问题还是完全不同的问题?

【问题讨论】:

标签: c++ visual-studio opencv visual-studio-2015


【解决方案1】:

据此: Returning from function crashing, only after a certain point in the code

我自己的经验(不幸的是)在 vs 2013 而不是 2015 中编译程序或者只是将平台工具集更改为 (v120) 足以让我修复错误

【讨论】:

    【解决方案2】:

    我也有同样的情况。 (opencv 3.0) 我试过了,然后 findcontours() 效果很好。

    我想,你已经输入了如下信息.. 链接器 --> 输入 (입력) --> 附加依赖项

    opencv_world300d.lib opencv_world300.lib opencv_ts300d.lib opencv_ts300.lib

    没有编辑库,我只是对齐它(300d.lib -> 300.lib) 并申请!而且效果很好!

    【讨论】:

      【解决方案3】:

      这可能是一个简单的链接问题。

      如果您在 Debug 模式下编译,则链接器需要输入变量 opencv_world310d.lib 而不是 opencv_world310.lib(注意点前的 d)。

      只有在编译Release模式时才需要输入opencv_world310.lib

      我遇到了同样的问题。花了我一天的时间来弄清楚。

      【讨论】:

      • 虽然这在理论上可以回答这个问题,it would be preferable 在此处包含答案的基本部分,并提供链接以供参考。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-18
      • 2012-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多