In particolare mi viene il sospetto che questa linea di codice:
codice:
float* obj_ptr = m_object.ptr<float>(0);
prepari uno smart pointer per un solo float, dove invece ti serve un array.
In questo caso la memcpy corrompe la memoria e l'effetto è di avere quella violazione.
Però in un'altra versione delle 2 funzioni compare quella istruzione e funziona tutto correttamente:
codice:
int extractAndMatchFeaturesSURF_F2F(IplImage *pRefImage,IplImage *pTrgImage, CvPoint2D32f *pRefCorners, CvPoint2D32f* pTrgCorners, int *pCorners)
{
CvSeq* refImgKeypoints = 0, *refImgDescriptors = 0;
CvSeq* trgImgKeypoints = 0, *trgImgDescriptors = 0;
CvSURFParams params = cvSURFParams(HESSIAN_THRESHOLD, 0);
CvMemStorage* storage = cvCreateMemStorage(0);
vector<int> ptpairs;
CvSize sImageSize=cvGetSize(pRefImage);
IplImage* pGrayRefImage=cvCreateImage(sImageSize,IPL_DEPTH_8U,1);
cvCvtColor(pRefImage,pGrayRefImage,CV_RGB2GRAY);
cvExtractSURF( pGrayRefImage, 0, &refImgKeypoints, &refImgDescriptors, storage, params );
IplImage* pGrayTrgImage=cvCreateImage(sImageSize,IPL_DEPTH_8U,1);
cvCvtColor(pTrgImage,pGrayTrgImage,CV_RGB2GRAY);
cvExtractSURF( pGrayTrgImage, 0, &trgImgKeypoints, &trgImgDescriptors, storage, params);
flannFindPairs_F2F( refImgKeypoints, refImgDescriptors, trgImgKeypoints, trgImgDescriptors, ptpairs );
*pCorners = (int)(ptpairs.size()/2);
if( *pCorners < 4 )
return 0;
int i;
for( i = 0; i < *pCorners; i++ )
{
pRefCorners[i] = ((CvSURFPoint*)cvGetSeqElem(refImgKeypoints,ptpairs[i*2]))->pt;
pTrgCorners[i] = ((CvSURFPoint*)cvGetSeqElem(trgImgKeypoints,ptpairs[i*2+1]))->pt;
}
}
codice:
void flannFindPairs_F2F( const CvSeq*, const CvSeq* objectDescriptors, const CvSeq*, const CvSeq* imageDescriptors, vector<int>& ptpairs )
{
int length = (int)(objectDescriptors->elem_size/sizeof(float));
cv::Mat m_object(objectDescriptors->total, length, CV_32F);
cv::Mat m_image(imageDescriptors->total, length, CV_32F);
// copy descriptors
CvSeqReader obj_reader;
float* obj_ptr = m_object.ptr<float>(0);
cvStartReadSeq( objectDescriptors, &obj_reader );
for(int i = 0; i < objectDescriptors->total; i++ )
{
const float* descriptor = (const float*)obj_reader.ptr;
CV_NEXT_SEQ_ELEM( obj_reader.seq->elem_size, obj_reader );
memcpy(obj_ptr, descriptor, length*sizeof(float));
obj_ptr += length;
}
CvSeqReader img_reader;
float* img_ptr = m_image.ptr<float>(0);
cvStartReadSeq( imageDescriptors, &img_reader );
for(int i = 0; i < imageDescriptors->total; i++ )
{
const float* descriptor = (const float*)img_reader.ptr;
CV_NEXT_SEQ_ELEM( img_reader.seq->elem_size, img_reader );
memcpy(img_ptr, descriptor, length*sizeof(float));
img_ptr += length;
}
// find nearest neighbors using FLANN
cv::Mat m_indices(objectDescriptors->total, 2, CV_32S);
cv::Mat m_dists(objectDescriptors->total, 2, CV_32F);
cv::flann::Index flann_index(m_image, cv::flann::KDTreeIndexParams(4)); // using 4 randomized kdtrees
flann_index.knnSearch(m_object, m_indices, m_dists, 2, cv::flann::SearchParams(64) ); // maximum number of leafs checked
int* indices_ptr = m_indices.ptr<int>(0);
float* dists_ptr = m_dists.ptr<float>(0);
for (int i=0;i<m_indices.rows;++i) {
if (dists_ptr[2*i]<0.6*dists_ptr[2*i+1]) {
ptpairs.push_back(i);
ptpairs.push_back(indices_ptr[2*i]);
}
}
}