2012-07-26 16 views
11

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.

+0

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? –

+1

@ 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

+0

'Todos los Configuratins -> General -> Platform Toolset -> Visual Studio 2010 (v100)' problema resuelto para mí. – vkalit

Respuesta

16

Está construyendo su aplicación en modo de depuración y enlazando con la DLL CRT de depuración multiproceso. ¿Sabes con qué CRT están vinculadas las DLL de OpenCV? Si está vinculado a un CRT estático, rellenará el vector con los datos asignados de un montón separado, lo que provoca una aserción en el CRT de depuración que está utilizando.

Si construye su aplicación en modo Release, ya no verá la afirmación, pero podría terminar perdiendo memoria. Lo mejor sería asegurarse de que tanto su aplicación como la (s) DLL (s) de OpenCV estén enlazadas con el mismo DLL CRT de subprocesos múltiples.

EDITAR: Si no puede reconstruir OpenCV para utilizar el mismo CRT que su aplicación, puede intentar decirle al vinculador que use la misma versión CRT que OpenCV para su aplicación modificando el manifiesto de la aplicación. Consulte How to Enforce C++ compiler to use specific CRT version? para obtener más información sobre cómo hacerlo.

+0

Descargué el código fuente de OpenCV y lo construí en mi máquina. No sé con qué está relacionado: no cambié la configuración preestablecida. ¿Dónde puedo ver esta información? Intenté compilar y ejecutar mi aplicación en modo Release, pero el problema persiste. – ShdNx

+0

Dependency Walker (http://www.dependencywalker.com/) puede mostrarle un archivo DLL/EXE determinado al que DLL tiene dependencias. Si algo llamado MSVC * aparece en el árbol de dependencias, puede compararlo con lo que está usando su aplicación. Si no se encuentra tal dependencia, la DLL probablemente esté vinculada estáticamente contra el CRT. – Michael

+0

Además, como mencionas que estás compilando OpenCV tú mismo (¿también usando Visual Studio?), Puedes acceder a las propiedades del proyecto al compilar OpenCV y asegurarte de que estás utilizando el mismo CRT que para tu aplicación (Generación de código -> Biblioteca de ejecución). – Michael

0

Vaya a sus opciones de solución, allí la configuración de c-runtime (CRT) y verifique los enlaces (CRT como se mencionó anteriormente) ... si su proyecto fue/es (una vez) creado con VS10 y utiliza uno más nuevo versión, solo edite los enlaces para no ser 10, sino 11 o 12 ..

0

Añadir a la ruta del sistema (como ejemplo): H: \ Source \ opencv_v2_4_13_2 \ salida \ bin \ Debug

donde directorio: "H: \ Source \ opencv_v2_4_13_2 \ output" se utiliza de CMake como directorio de destino para los proyectos de Visual Studio 14 (2015) opencv.

Su proyecto utiliza archivos dll OpenCV, pero no se encontró: opencv_core2413d.dll

Cuestiones relacionadas