Estoy tratando de comenzar con la detección de contornos en OpenCV 2.4.2. Con este fin, configuré un proyecto para OpenCV y copié todo el código de ejemplo que se encuentra en el documentation. En el futuro, aquí está el código:Código de ejemplo de OpenCV para buscar contornos: problema de desasignación de vectores
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace cv;
using namespace std;
Mat src; Mat src_gray;
int thresh = 100;
int max_thresh = 255;
RNG rng(12345);
/// Function header
void thresh_callback(int, void*);
/** @function main */
int main(int argc, char** argv)
{
/// Load source image and convert it to gray
src = imread(argv[1], 1);
/// Convert image to gray and blur it
cvtColor(src, src_gray, CV_BGR2GRAY);
blur(src_gray, src_gray, Size(3,3));
/// Create Window
char* source_window = "Source";
namedWindow(source_window, CV_WINDOW_AUTOSIZE);
imshow(source_window, src);
createTrackbar(" Canny thresh:", "Source", &thresh, max_thresh, thresh_callback);
thresh_callback(0, 0);
waitKey(0);
return(0);
}
/** @function thresh_callback */
void thresh_callback(int, void*)
{
Mat canny_output;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
/// Detect edges using canny
Canny(src_gray, canny_output, thresh, thresh*2, 3);
/// Find contours
findContours(canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
/// Draw contours
Mat drawing = Mat::zeros(canny_output.size(), CV_8UC3);
for(int i = 0; i< contours.size(); i++)
{
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255));
drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point());
}
/// Show in a window
namedWindow("Contours", CV_WINDOW_AUTOSIZE);
imshow("Contours", drawing);
contours.clear(); // Error!!
}
Se compila bien en Visual Studio 11 RC (7 SP1 de Windows), pero me da un error al final de la función thresh_callback
. Aquí está el StackTrace:
msvcr110d.dll!_CrtIsValidHeapPointer(const void * pUserData) Line 2036
msvcr110d.dll!_free_dbg_nolock(void * pUserData, int nBlockUse) Line 1322
msvcr110d.dll!_free_dbg(void * pUserData, int nBlockUse) Line 1265
msvcr110d.dll!operator delete(void * pUserData) Line 54
std::allocator<cv::Point_<int> >::deallocate(cv::Point_<int> * _Ptr, unsigned int __formal) Line 586
std::_Wrap_alloc<std::allocator<cv::Point_<int> > >::deallocate(cv::Point_<int> * _Ptr, unsigned int _Count) Line 888
std::vector<cv::Point_<int>,std::allocator<cv::Point_<int> > >::_Tidy() Line 1542
std::vector<cv::Point_<int>,std::allocator<cv::Point_<int> > >::~vector<cv::Point_<int>,std::allocator<cv::Point_<int> > >() Line 901
std::vector<cv::Point_<int>,std::allocator<cv::Point_<int> > >::`scalar deleting destructor'(unsigned int)
std::allocator<std::vector<cv::Point_<int>,std::allocator<cv::Point_<int> > > >::destroy<std::vector<cv::Point_<int>,std::allocator<cv::Point_<int> > > >(std::<cv::Point_<int>,std::allocator<cv::Point_<int> > > * _Ptr) Line 624
std::allocator_traits<std::allocator<std::vector<cv::Point_<int>,std::allocator<cv::Point_<int> > > > >::destroy<std::vector<cv::Point_<int>,std::allocator<cv::Point_<int> > > >(std::allocator<std::vector<cv::Point_<int>,std::allocator<cv::Point_<int> > > > & _Al, std::vector<cv::Point_<int>,std::allocator<cv::Point_<int> > > * _Ptr)758
std::_Wrap_alloc<std::allocator<std::vector<cv::Point_<int>,std::allocator<cv::Point_<int> > > > >::destroy<std::vector<cv::Point_<int>,std::allocator<cv::Poin> > > >(std::vector<cv::Point_<int>,std::allocator<cv::Point_<int> > > * _Ptr) Line 909
std::_Destroy_range<std::_Wrap_alloc<std::allocator<std::vector<cv::Point_<int>,std::allocator<cv::Point_<int> > > > > >(std::vector<cv::Point_<int>,std::allocator<cv::Point_<int> > > * _First, std::vector<cv::Point_<int>,std::allocator<cv::Point_<int> > > * _Last, std::_Wrap_alloc<std::allocator<std::vector<cv::Point_<int>,std::allocator<cv::<int> > > > > & _Al, std::_Nonscalar_ptr_iterator_tag __formal) Line 89
std::_Destroy_range<std::_Wrap_alloc<std::allocator<std::vector<cv::Point_<int>,std::allocator<cv::Point_<int> > > > > >(std::vector<cv::Point_<int>,std::allocator<cv::Point_<int> > > * _First, std::vector<cv::Point_<int>,std::allocator<cv::Point_<int> > > * _Last, std::_Wrap_alloc<std::allocator<std::vector<cv::Point_<int>,std::allocator<cv::<int> > > > > & _Al) Line 80
std::vector<std::vector<cv::Point_<int>,std::allocator<cv::Point_<int> > >,std::allocator<std::vector<cv::Point_<int>,std::allocator<cv::Point_<int> >::_Destroy(std::vector<cv::Point_<int>,std::allocator<cv::Point_<int> > > * _First, std::vector<cv::Point_<int>,std::allocator<cv::Point_<int> > > * _Last) Line 1480
std::vector<std::vector<cv::Point_<int>,std::allocator<cv::Point_<int> > >,std::allocator<std::vector<cv::Point_<int>,std::allocator<cv::Point_<int> > > > >::c Line 1416
thresh_callback(int __formal, void * __formal) Line 143
opencv_highgui242d.dll!icvUpdateTrackbar(CvTrackbar * trackbar, int pos) Line 1938
opencv_highgui242d.dll!HGToolbarProc(HWND__ * hwnd, unsigned int uMsg, unsigned int wParam, long lParam) Line 1982
(Tenga en cuenta que en realidad tengo una versión ligeramente modificada del código de ejemplo, añadido unos cuantos printf-s, y una llamada contours.clear()
, que está en la línea 143, y que desencadena el vector desasignación [que sucedería automáticamente al final de la función] que parece ser la fuente del problema. El mismo problema ocurre con el código de ejemplo exacto también).
El problema parece ser la desasignación de el vector contours
. Lo mismo ocurre si trato de llamar al contours.clear()
. He examinado el contenido de la variable en el depurador VS, pero no hay nada inusual en lo que puedo decir.
He intentado borrar el vector tan pronto como ya no era necesario (después del bucle for
), pero no ayudó. También traté de cambiar el conjunto de herramientas de la plataforma de Visual Studio 10, que a su vez ni siquiera compilar con mensajes de error que están más allá de mí:
error C1083: Cannot open include file: 'SDKDDKVer.h': No such file or directory (C:\<project path>\targetver.h) (Line 8, Column 1)
IntelliSense: cannot open source file "SDKDDKVer.h" (C:\<project path>\targetver.h) (Line 8, Column 1)
IntelliSense: cannot open source file "windows.h" (C:\<opencv path>\build\include\opencv2\core\operations.hpp (Line 83, Column 3)
Cualquier ayuda sería muy apreciada. Tenga en cuenta que no soy un programador de C++: tengo muy poco conocimiento, e incluso menos experiencia con la programación C++ y la programación nativa en general.
Editar: resulta que el depurador muestra una línea incorrecta como fuente de error. Debería haber visto en la pila de llamadas que el problema era con vector>. ¡Entonces el vector problemático es contours
, no hierarchy
!
Edición # 2: También traté de reproducir el problema con un código mínimo que crea un vector<vector<cv::Point> >
, pone algunos elementos en ella, y luego despejó, pero no podía reproducir el problema.
Usted sabe que no hay necesidad de objetos transparentes de los contornos, ¿verdad? Se recolectará basura al final de la llamada a la función thresh_callback. ¿Funciona tu código sin esta línea? –
@ RégisB .: Creo que lo mencioné en mi pregunta que el mismo error ocurre sin la línea. La única razón por la que llamo explícitamente 'contours.clear' aquí es para destacar dónde está ocurriendo el problema. – ShdNx
'Todos los Configuratins -> General -> Platform Toolset -> Visual Studio 2010 (v100)' problema resuelto para mí. – vkalit