Tôi đang cố bắt đầu dò tìm đường viền trong OpenCV 2.4.2. Để kết thúc này, tôi thiết lập một dự án cho OpenCV và sao chép toàn bộ mã ví dụ được tìm thấy trong documentation. Để tham khảo trong tương lai, đây là mã:Mã ví dụ OpenCV để tìm đường bao: vấn đề deallocation vector
#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!!
}
Nó biên dịch tốt trong Visual Studio 11 RC (Windows 7 SP1), nhưng tôi nhận được một lỗi ở phần cuối của thresh_callback
chức năng. Đây là 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
(Lưu ý rằng thực sự tôi có một phiên bản sửa đổi một chút các mã ví dụ, thêm một vài printf-s, và một contours.clear()
cuộc gọi, đó là tại dòng 143, và đó gây nên các vector deallocation [điều đó sẽ xảy ra tự động ở cuối hàm] mà dường như là nguồn gốc của vấn đề. Vấn đề tương tự cũng xảy ra với mã ví dụ chính xác.)
Vấn đề có vẻ là với sự thỏa thuận vector contours
. Điều tương tự cũng xảy ra nếu tôi cố gắng gọi contours.clear()
. Tôi đã kiểm tra nội dung của biến trong trình gỡ rối VS, nhưng không có gì khác thường như tôi có thể nói.
Tôi đã cố gắng xóa véc-tơ ngay sau khi nó không còn cần thiết nữa (sau vòng lặp for
), nhưng không hiệu quả. Tôi cũng đã cố gắng để chuyển đổi Platform Toolset để Visual Studio 10, mà lần lượt sẽ không biên dịch với các thông báo lỗi vượt ra ngoài tôi:
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)
Bất kỳ trợ giúp sẽ được đánh giá rất nhiều. Xin lưu ý rằng tôi không phải là lập trình viên C++: Tôi có rất ít kiến thức và thậm chí ít kinh nghiệm hơn với lập trình C++ và lập trình bản địa nói chung.
Chỉnh sửa: hóa ra trình gỡ lỗi hiển thị dòng sai là nguồn lỗi. Tôi nên đã nhìn thấy trong cuộc gọi ngăn xếp rằng vấn đề là với vector>. Vì vậy, vectơ có vấn đề là contours
, không phải hierarchy
!
Chỉnh sửa # 2: Tôi cũng cố gắng tạo lại vấn đề với mã tối thiểu tạo vector<vector<cv::Point> >
, đặt một số mục vào đó, sau đó xóa nó, nhưng tôi không thể tái tạo sự cố.
Bạn biết rằng không có nhu cầu để xóa đối tượng những đường nét, đúng không? Nó sẽ được thu gom rác vào cuối cuộc gọi hàm thresh_callback. Mã của bạn có hoạt động không có dòng này không? –
@ RégisB .: Tôi tin rằng tôi đã đề cập đến nó trong câu hỏi của tôi rằng cùng một lỗi xảy ra mà không có dòng. Lý do duy nhất tôi gọi một cách rõ ràng là 'contours.clear' ở đây là để làm nổi bật nơi xảy ra sự cố. – ShdNx
'Tất cả cấu hình -> Chung -> Platform Toolset -> Visual Studio 2010 (v100)' giải quyết vấn đề cho tôi. – vkalit