// deallocate underlying CvMat or IplImage data CV_IMPL void cvReleaseData( CvArr* arr ) { CV_FUNCNAME( "cvReleaseData" ); __BEGIN__; if( _CV_IS_ARR( arr )) { CvMat* mat = (CvMat*)arr; uchar* data = mat->data.ptr; mat->data.ptr = 0; cvFree( (void**)&data ); } else if( _CV_IS_IMAGE( arr )) { IplImage* img = (IplImage*)arr; if( !CvIPL.deallocate ) { char* ptr = img->imageData; img->imageData = img->imageDataOrigin = 0; cvFree( (void**)&ptr ); } else { CvIPL.deallocate( img, IPL_IMAGE_DATA ); } } else { CV_ERROR( CV_StsBadArg, "" ); } __END__; }
static void icvTestSeqReleaseAll(CvTestSeqElem** ppElemList) { CvTestSeqElem* p = ppElemList[0]; while(p) { CvTestSeqElem* pd = p; if(p->pAVI) { //cvReleaseCapture(&p->pAVI); } if(p->pImg)cvReleaseImage(&p->pImg); if(p->pImgMask)cvReleaseImage(&p->pImgMask); if(p->pPos)cvFree(&p->pPos); if(p->pTrans)cvFree(&p->pTrans); if(p->pSize)cvFree(&p->pSize); p=p->next; cvFree(&pd); } /* Next element. */ ppElemList[0] = NULL; } /* icvTestSeqReleaseAll */
void cvReleaseStereoBMState( CvStereoBMState** state ) { if( !state ) CV_Error( CV_StsNullPtr, "" ); if( !*state ) return; cvReleaseMat( &(*state)->preFilteredImg0 ); cvReleaseMat( &(*state)->preFilteredImg1 ); cvReleaseMat( &(*state)->slidingSumBuf ); cvReleaseMat( &(*state)->disp ); cvReleaseMat( &(*state)->cost ); cvFree( state ); }
/*! * Method returns one frame (IplImage). */ bool V4L::retFrame() { if (ioctl(video_dev, VIDIOCSYNC, &((*(v_map + bufferIndex)).frame)) == -1) { LOG(LERROR) << "function: retFrame\n"; return false; } if ((frame.width != (*(v_map + bufferIndex)).width) || (frame.height != (*(v_map + bufferIndex)).height)) { cvFree(&(frame.imageData)); cvInitImageHeader(&frame, cvSize(win.width, win.height), IPL_DEPTH_8U, 3, IPL_ORIGIN_TL, 4); frame.imageData = (char *) cvAlloc(frame.imageSize); } memcpy((char *) (frame.imageData), (char *) (map + m_buf.offsets[bufferIndex]), frame.imageSize); //memcpy((char *)(original_frame.imageData),(char *)(map + m_buf.offsets[bufferIndex]),original_frame.imageSize); /* switch(pic.palette) { case RGB24: memcpy((char *)(frame.imageData),(char *)(map + m_buf.offsets[bufferIndex]),frame.imageSize); break; case YUV422P: yuv420p_to_rgb24(win.width, win.height, (unsigned char*)(map + m_buf.offsets[bufferIndex]), (unsigned char*)frame.imageData); break; case YUV420: yuv420_to_rgb24(win.width, win.height, (unsigned char*)(map + m_buf.offsets[bufferIndex]), (unsigned char*)frame.imageData); break; case YUV411P: yuv411p_to_rgb24(win.width, win.height, (unsigned char*)(map + m_buf.offsets[bufferIndex]), (unsigned char*)frame.imageData); break; default: printf("format is not supported V4L\n"); return false; }*/ return true; }
void icvReleaseCascadeHaarClassifier( CvIntHaarClassifier** classifier ) { int i; for( i = 0; i < ((CvCascadeHaarClassifier*) *classifier)->count; i++ ) { if( ((CvCascadeHaarClassifier*) *classifier)->classifier[i] != NULL ) { ((CvCascadeHaarClassifier*) *classifier)->classifier[i]->release( &(((CvCascadeHaarClassifier*) *classifier)->classifier[i]) ); } } cvFree( classifier ); *classifier = NULL; }
int main() { IplImage *image = cvCreateImageHeader(cvSize(640,480), 8, 3); while (cvWaitKey(10) < 0) { char *data; unsigned int timestamp; freenect_sync_get_video((void**)(&data), ×tamp, 0, FREENECT_VIDEO_RGB); cvSetData(image, data, 640*3); cvCvtColor(image, image, CV_RGB2BGR); cvShowImage("RGB", image); } freenect_sync_stop(); cvFree(&image); return EXIT_SUCCESS; }
void cvReleaseStereoGCState(CvStereoGCState** _state) { CvStereoGCState* state; if (!_state && !*_state) { return; } state = *_state; cvReleaseMat(&state->left); cvReleaseMat(&state->right); cvReleaseMat(&state->ptrLeft); cvReleaseMat(&state->ptrRight); cvReleaseMat(&state->vtxBuf); cvReleaseMat(&state->edgeBuf); cvFree(_state); }
int main (int argc, char **argv) { int i, img_num; const char defaultfile[2][32] = {"../image/moon.png", "../image/sunset.png"}; int total_width=0, max_height=0; IplImage **src_img; IplImage *combined_img; CvRect roi = cvRect(0, 0, 0, 0); // (1)load all images specified on the command line img_num = argc > 1 ? argc-1 : 2; src_img = (IplImage**)cvAlloc(sizeof(IplImage*)*img_num); for(i=0; i<img_num; i++) { src_img[i] = cvLoadImage (argc-1?argv[i+1]:defaultfile[i], CV_LOAD_IMAGE_COLOR); if(src_img[i] == 0) return -1; total_width += src_img[i]->width; max_height = max_height < src_img[i]->height ? src_img[i]->height : max_height; } // (2)append images one after another combined_img = cvCreateImage(cvSize(total_width, max_height), IPL_DEPTH_8U, 3); cvZero(combined_img); for(i=0; i<img_num; i++) { roi.width = src_img[i]->width; roi.height = src_img[i]->height; cvSetImageROI(combined_img, roi); cvCopy(src_img[i], combined_img, NULL); roi.x += roi.width; } cvResetImageROI(combined_img); // (3)show the combined image, and quit when any key pressed cvNamedWindow ("Image", CV_WINDOW_AUTOSIZE); cvShowImage ("Image", combined_img); cvWaitKey (0); cvDestroyWindow("Image"); cvReleaseImage(&combined_img); for(i=0; i<img_num; i++) { cvReleaseImage(&src_img[i]); } cvFree(&src_img); return 0; }
/* Release all blocks of the storage (or return them to parent, if any): */ static void icvDestroyMemStorage( CvMemStorage* storage ) { int k = 0; CvMemBlock *block; CvMemBlock *dst_top = 0; if( !storage ) CV_Error( CV_StsNullPtr, "" ); if( storage->parent ) dst_top = storage->parent->top; for( block = storage->bottom; block != 0; k++ ) { CvMemBlock *temp = block; block = block->next; if( storage->parent ) { if( dst_top ) { temp->prev = dst_top; temp->next = dst_top->next; if( temp->next ) temp->next->prev = temp; dst_top = dst_top->next = temp; } else { dst_top = storage->parent->bottom = storage->parent->top = temp; temp->prev = temp->next = 0; storage->free_space = storage->block_size - sizeof( *temp ); } } else { cvFree( &temp ); } } storage->top = storage->bottom = 0; storage->free_space = 0; }
bool CvCalibFilter::Push( const CvPoint2D32f** pts ) { bool result = true; int i, newMaxPoints = etalonPointCount*(MAX(framesAccepted,framesTotal) + 1); isCalibrated = false; if( !pts ) { for( i = 0; i < cameraCount; i++ ) if( latestCounts[i] <= 0 ) return false; pts = (const CvPoint2D32f**)latestPoints; } for( i = 0; i < cameraCount; i++ ) { if( !pts[i] ) { assert(0); break; } if( maxPoints < newMaxPoints ) { CvPoint2D32f* prev = points[i]; cvFree( points + i ); points[i] = (CvPoint2D32f*)cvAlloc( newMaxPoints * sizeof(prev[0])); memcpy( points[i], prev, maxPoints * sizeof(prev[0])); } memcpy( points[i] + framesAccepted*etalonPointCount, pts[i], etalonPointCount*sizeof(points[0][0])); } if( maxPoints < newMaxPoints ) maxPoints = newMaxPoints; result = i == cameraCount; if( ++framesAccepted >= framesTotal ) Stop( true ); return result; }
int main (int argc, char **argv) { char filename[] = "save_cv.xml"; // file name int i; int a; float b; CvMat** mat; CvFileStorage *cvfs; // (1)create sample data a = 10; b = 0.1; mat = (CvMat**)cvAlloc(3*sizeof(CvMat*)); for(i=0;i<3;i++){ mat[i] = cvCreateMat(3,3,CV_32FC1); cvSet(mat[i], cvScalarAll(i), NULL); } // (2)open file storage cvfs = cvOpenFileStorage(filename,NULL,CV_STORAGE_WRITE); // (3)write data to file cvWriteInt(cvfs, "a", a); cvWriteReal(cvfs, "b", b); cvStartWriteStruct(cvfs, "mat_array", CV_NODE_SEQ, NULL, cvAttrList(NULL, NULL)); // create node for(i=0; i<3; i++){ cvWrite(cvfs, NULL, mat[i], cvAttrList(NULL, NULL)); } cvEndWriteStruct(cvfs); // (4)close file storage cvReleaseFileStorage(&cvfs); // release mat for(i=0; i<3; i++){ cvReleaseMat(mat+i); } cvFree(mat); return 0; }
// Append the body of the input vec to the ouput vec void icvAppendVec( CvVecFile &in, CvVecFile &out, int *showsamples, int winwidth, int winheight ) { CvMat* sample; if( *showsamples ) { cvNamedWindow( "Sample", CV_WINDOW_AUTOSIZE ); } if( !feof( in.input ) ) { in.last = 0; in.vector = (short*) cvAlloc( sizeof( *in.vector ) * in.vecsize ); if ( *showsamples ) { if ( in.vecsize != winheight * winwidth ) { fprintf( stderr, "ERROR: -show: the size of images inside of vec files does not match with %d x %d, but %d\n", winheight, winwidth, in.vecsize ); exit(1); } sample = cvCreateMat( winheight, winwidth, CV_8UC1 ); } else { sample = cvCreateMat( in.vecsize, 1, CV_8UC1 ); } for( int i = 0; i < in.count; i++ ) { icvGetHaarTraininDataFromVecCallback( sample, &in ); icvWriteVecSample ( out.input, sample ); if( *showsamples ) { cvShowImage( "Sample", sample ); if( cvWaitKey( 0 ) == 27 ) { *showsamples = 0; } } } cvReleaseMat( &sample ); cvFree( (void**) &in.vector ); } }
// Extract images from a vec file void icvVec2Img( const char* vecname, const char* outformat, int width, int height ) { CvVecFile vec; CvMat* sample; char outfilename[PATH_MAX]; short tmp; vec.input = fopen( vecname, "rb" ); if ( vec.input == NULL ) { fprintf( stderr, "ERROR: Input file %s does not exist or not readable.\n", vecname); exit(1); } fread( &vec.count, sizeof( vec.count ), 1, vec.input ); fread( &vec.vecsize, sizeof( vec.vecsize ), 1, vec.input ); fread( &tmp, sizeof( tmp ), 1, vec.input ); fread( &tmp, sizeof( tmp ), 1, vec.input ); if( !feof( vec.input ) ) { vec.last = 0; vec.vector = (short*) cvAlloc( sizeof( *vec.vector ) * vec.vecsize ); if( vec.vecsize != width * height ) { fprintf( stderr, "ERROR: The size of images inside of vec files does not match with %d x %d, but %d. \n", height, width, vec.vecsize ); exit(1); } sample = cvCreateMat( height, width, CV_8UC1 ); //cvNamedWindow( "Sample", CV_WINDOW_AUTOSIZE ); for( int i = 0; i < vec.count; i++ ) { icvGetHaarTraininDataFromVecCallback( sample, &vec ); sprintf( outfilename, outformat, i + 1 ); printf( "%s\n", outfilename ); cvSaveImage( outfilename, sample ); //cvShowImage( "Sample", sample ); cvWaitKey( 0 ); } cvReleaseMat( &sample ); cvFree( (void**) &vec.vector ); } fclose( vec.input ); }
IplImage* C920Camera::RetrieveFrame(V4L2CameraCapture* capture) { // Resize Frame if Format size has changed. if (((unsigned long) capture->Frame.width != capture->V4L2Format.fmt.pix.width) || ((unsigned long) capture->Frame.height != capture->V4L2Format.fmt.pix.height)) { cvFree(&capture->Frame.imageData); cvInitImageHeader(&capture->Frame, cvSize(capture->V4L2Format.fmt.pix.width, capture->V4L2Format.fmt.pix.height), IPL_DEPTH_8U, 3, IPL_ORIGIN_TL, 4); capture->Frame.imageData = (char *) cvAlloc(capture->Frame.imageSize); } // Decode image from MJPEG to RGB24 if (capture->Buffers[capture->BufferIndex].start) { if (!this->MJPEG2RGB24(capture->V4L2Format.fmt.pix.width, capture->V4L2Format.fmt.pix.height, (unsigned char*) (capture->Buffers[capture->BufferIndex].start), capture->Buffers[capture->BufferIndex].length, (unsigned char*) capture->Frame.imageData)) { fprintf(stdout, "C920Camera::RetrieveFrame ERROR: Unable to decode frame.\n"); return 0; } } return (&capture->Frame); }
void vpKltOpencv::cleanAll() { clean(); if (features) cvFree(&features); if (prev_features) cvFree(&prev_features); if (status) cvFree(&status); if (lostDuringTrack) cvFree(&lostDuringTrack); if (featuresid) cvFree(&featuresid); if (prev_featuresid) cvFree(&prev_featuresid); features = NULL; prev_features = NULL; status = NULL; lostDuringTrack = 0; featuresid = NULL; prev_featuresid = NULL; }
// deallocate CvMat header CV_IMPL void cvReleaseMatHeader( CvMat** array ) { CV_FUNCNAME( "cvReleaseMatHeader" ); __BEGIN__; if( !array ) CV_ERROR_FROM_CODE( CV_HeaderIsNull ); if( *array ) { CvMat* arr = *array; if( !_CV_IS_ARR( arr )) CV_ERROR_FROM_CODE( !arr ? CV_StsNullPtr : CV_StsBadFlag ); *array = 0; cvFree( (void**)&arr ); } __END__; }
void cvReleaseGLCM( CvGLCM** GLCM, int flag ) { CV_FUNCNAME( "cvReleaseGLCM" ); __BEGIN__; int matrixLoop; if( !GLCM ) CV_ERROR( CV_StsNullPtr, "" ); if( !(*GLCM) ) EXIT; // repeated deallocation: just skip it. if( (flag == CV_GLCM_GLCM || flag == CV_GLCM_ALL) && (*GLCM)->matrices ) { for( matrixLoop = 0; matrixLoop < (*GLCM)->numMatrices; matrixLoop++ ) { if( (*GLCM)->matrices[ matrixLoop ] ) { cvFree( (*GLCM)->matrices[matrixLoop] ); cvFree( (*GLCM)->matrices + matrixLoop ); } } cvFree( &((*GLCM)->matrices) ); } if( (flag == CV_GLCM_DESC || flag == CV_GLCM_ALL) && (*GLCM)->descriptors ) { for( matrixLoop = 0; matrixLoop < (*GLCM)->numMatrices; matrixLoop++ ) { cvFree( (*GLCM)->descriptors + matrixLoop ); } cvFree( &((*GLCM)->descriptors) ); } if( flag == CV_GLCM_ALL ) { cvFree( GLCM ); } __END__; }
/*! Set the maximum number of features to track in the image. \warning The tracker must be re-initialised using the method initTracking(). \param input : The new number of maximum features. */ void vpKltOpencv::setMaxFeatures(const int input) { initialized = 0; maxFeatures=input; if (features) cvFree(&features); if (prev_features) cvFree(&prev_features); if (status) cvFree(&status); if (lostDuringTrack) cvFree(&lostDuringTrack); if (featuresid) cvFree(&featuresid); if (prev_featuresid) cvFree(&prev_featuresid); features = (CvPoint2D32f*)cvAlloc((unsigned int)maxFeatures*sizeof(CvPoint2D32f)); prev_features = (CvPoint2D32f*)cvAlloc((unsigned int)maxFeatures*sizeof(CvPoint2D32f)); status = (char*)cvAlloc((unsigned int)maxFeatures*sizeof(char)); lostDuringTrack = (bool*)cvAlloc((unsigned int)maxFeatures*sizeof(bool)); featuresid = (long*)cvAlloc((unsigned int)maxFeatures*sizeof(long)); prev_featuresid = (long*)cvAlloc((unsigned int)maxFeatures*sizeof(long)); }
void * MARS_VideoReader::videoReadLoop(){ string fname = this->getNextFilename(); printf("Reading in %s...\n", fname.c_str()); //## Setup the opencv Reader CvVideoReader *Reader = NULL; //IplImage *imgrgb= cvCreateImage(cvSize(windowWidth,windowHeight), IPL_DEPTH_8U, 3), * img = cvCreateImage(cvSize(windowWidth,windowHeight), IPL_DEPTH_8U, 3); cvFree(&img->imageDataOrigin); img->origin = 0; // Main loop while( this->recording){ //dequeue a frame BufferItem* bi = this->dequeue(); //openwill wait for the semaphore to be > 0, and then mutex lock/unlock the buffer for access. if (!this->recording){ //check right after the dequeue as well, in case sem_post was called to unwait this thread from MARS_VideoReader::stop break; } //convert to IplImage img->imageData = bi->framedata; img->imageDataOrigin = bi->framedata; cvFlip(img, NULL, 0); cvCvtColor(img, imgrgb, CV_BGR2RGB); //Read the frame to disk cvReadFrame(Reader,imgrgb); //cleanup the memory associated with the frame delete bi; } cvReleaseVideoReader(&Reader); //## Exit cleanly sched_yield(); usleep(1000); printf("Closing %s.\n", fname.c_str()); return(0); }
CV_IMPL void cvUnregisterType( const char* type_name ) { CvTypeInfo* info; info = cvFindType( type_name ); if( info ) { if( info->prev ) info->prev->next = info->next; else CvType::first = info->next; if( info->next ) info->next->prev = info->prev; else CvType::last = info->prev; if( !CvType::first || !CvType::last ) CvType::first = CvType::last = 0; cvFree( &info ); } }
bool CvCalibFilter::SetEtalon( CvCalibEtalonType type, double* params, int pointCount, CvPoint2D32f* _points ) { int i, arrSize; Stop(); if (latestPoints != NULL) { for( i = 0; i < MAX_CAMERAS; i++ ) cvFree( latestPoints + i ); } if( type == CV_CALIB_ETALON_USER || type != etalonType ) { if (etalonParams != NULL) { cvFree( &etalonParams ); } } etalonType = type; switch( etalonType ) { case CV_CALIB_ETALON_CHESSBOARD: etalonParamCount = 3; if( !params || cvRound(params[0]) != params[0] || params[0] < 3 || cvRound(params[1]) != params[1] || params[1] < 3 || params[2] <= 0 ) { assert(0); return false; } pointCount = cvRound((params[0] - 1)*(params[1] - 1)); break; case CV_CALIB_ETALON_USER: etalonParamCount = 0; if( !_points || pointCount < 4 ) { assert(0); return false; } break; default: assert(0); return false; } if( etalonParamCount > 0 ) { arrSize = etalonParamCount * sizeof(etalonParams[0]); etalonParams = (double*)cvAlloc( arrSize ); } arrSize = pointCount * sizeof(etalonPoints[0]); if( etalonPointCount != pointCount ) { if (etalonPoints != NULL) { cvFree( &etalonPoints ); } etalonPointCount = pointCount; etalonPoints = (CvPoint2D32f*)cvAlloc( arrSize ); } switch( etalonType ) { case CV_CALIB_ETALON_CHESSBOARD: { int etalonWidth = cvRound( params[0] ) - 1; int etalonHeight = cvRound( params[1] ) - 1; int x, y, k = 0; etalonParams[0] = etalonWidth; etalonParams[1] = etalonHeight; etalonParams[2] = params[2]; for( y = 0; y < etalonHeight; y++ ) for( x = 0; x < etalonWidth; x++ ) { etalonPoints[k++] = cvPoint2D32f( (etalonWidth - 1 - x)*params[2], y*params[2] ); } } break; case CV_CALIB_ETALON_USER: if (params != NULL) { memcpy( etalonParams, params, arrSize ); } if (_points != NULL) { memcpy( etalonPoints, _points, arrSize ); } break; default: assert(0); return false; } return true; }
void CvCalibFilter::Stop( bool calibrate ) { int i, j; isCalibrated = false; // deallocate undistortion maps for( i = 0; i < cameraCount; i++ ) { cvReleaseMat( &undistMap[i][0] ); cvReleaseMat( &undistMap[i][1] ); cvReleaseMat( &rectMap[i][0] ); cvReleaseMat( &rectMap[i][1] ); } if( calibrate && framesAccepted > 0 ) { int n = framesAccepted; CvPoint3D32f* buffer = (CvPoint3D32f*)cvAlloc( n * etalonPointCount * sizeof(buffer[0])); CvMat mat; float* rotMatr = (float*)cvAlloc( n * 9 * sizeof(rotMatr[0])); float* transVect = (float*)cvAlloc( n * 3 * sizeof(transVect[0])); int* counts = (int*)cvAlloc( n * sizeof(counts[0])); cvInitMatHeader( &mat, 1, sizeof(CvCamera)/sizeof(float), CV_32FC1, 0 ); memset( cameraParams, 0, cameraCount * sizeof(cameraParams[0])); for( i = 0; i < framesAccepted; i++ ) { counts[i] = etalonPointCount; for( j = 0; j < etalonPointCount; j++ ) buffer[i * etalonPointCount + j] = cvPoint3D32f( etalonPoints[j].x, etalonPoints[j].y, 0 ); } for( i = 0; i < cameraCount; i++ ) { cvCalibrateCamera( framesAccepted, counts, imgSize, points[i], buffer, cameraParams[i].distortion, cameraParams[i].matrix, transVect, rotMatr, 0 ); cameraParams[i].imgSize[0] = (float)imgSize.width; cameraParams[i].imgSize[1] = (float)imgSize.height; // cameraParams[i].focalLength[0] = cameraParams[i].matrix[0]; // cameraParams[i].focalLength[1] = cameraParams[i].matrix[4]; // cameraParams[i].principalPoint[0] = cameraParams[i].matrix[2]; // cameraParams[i].principalPoint[1] = cameraParams[i].matrix[5]; memcpy( cameraParams[i].rotMatr, rotMatr, 9 * sizeof(rotMatr[0])); memcpy( cameraParams[i].transVect, transVect, 3 * sizeof(transVect[0])); mat.data.ptr = (uchar*)(cameraParams + i); /* check resultant camera parameters: if there are some INF's or NAN's, stop and reset results */ if( !cvCheckArr( &mat, CV_CHECK_RANGE | CV_CHECK_QUIET, -10000, 10000 )) break; } isCalibrated = i == cameraCount; {/* calibrate stereo cameras */ if( cameraCount == 2 ) { stereo.camera[0] = &cameraParams[0]; stereo.camera[1] = &cameraParams[1]; icvStereoCalibration( framesAccepted, counts, imgSize, points[0],points[1], buffer, &stereo); for( i = 0; i < 9; i++ ) { stereo.fundMatr[i] = stereo.fundMatr[i]; } } } cvFree( &buffer ); cvFree( &counts ); cvFree( &rotMatr ); cvFree( &transVect ); } framesAccepted = 0; }
/* area of a contour sector */ static double icvContourSecArea( CvSeq * contour, CvSlice slice ) { CvPoint pt; /* pointer to points */ CvPoint pt_s, pt_e; /* first and last points */ CvSeqReader reader; /* points reader of contour */ int p_max = 2, p_ind; int lpt, flag, i; double a00; /* unnormalized moments m00 */ double xi, yi, xi_1, yi_1, x0, y0, dxy, sk, sk1, t; double x_s, y_s, nx, ny, dx, dy, du, dv; double eps = 1.e-5; double *p_are1, *p_are2, *p_are; double area = 0; CV_Assert( contour != NULL && CV_IS_SEQ_POINT_SET( contour )); lpt = cvSliceLength( slice, contour ); /*if( n2 >= n1 ) lpt = n2 - n1 + 1; else lpt = contour->total - n1 + n2 + 1;*/ if( contour->total <= 0 || lpt <= 2 ) return 0.; a00 = x0 = y0 = xi_1 = yi_1 = 0; sk1 = 0; flag = 0; dxy = 0; p_are1 = (double *) cvAlloc( p_max * sizeof( double )); p_are = p_are1; p_are2 = NULL; cvStartReadSeq( contour, &reader, 0 ); cvSetSeqReaderPos( &reader, slice.start_index ); CV_READ_SEQ_ELEM( pt_s, reader ); p_ind = 0; cvSetSeqReaderPos( &reader, slice.end_index ); CV_READ_SEQ_ELEM( pt_e, reader ); /* normal coefficients */ nx = pt_s.y - pt_e.y; ny = pt_e.x - pt_s.x; cvSetSeqReaderPos( &reader, slice.start_index ); while( lpt-- > 0 ) { CV_READ_SEQ_ELEM( pt, reader ); if( flag == 0 ) { xi_1 = (double) pt.x; yi_1 = (double) pt.y; x0 = xi_1; y0 = yi_1; sk1 = 0; flag = 1; } else { xi = (double) pt.x; yi = (double) pt.y; /**************** edges intersection examination **************************/ sk = nx * (xi - pt_s.x) + ny * (yi - pt_s.y); if( (fabs( sk ) < eps && lpt > 0) || sk * sk1 < -eps ) { if( fabs( sk ) < eps ) { dxy = xi_1 * yi - xi * yi_1; a00 = a00 + dxy; dxy = xi * y0 - x0 * yi; a00 = a00 + dxy; if( p_ind >= p_max ) icvMemCopy( &p_are1, &p_are2, &p_are, &p_max ); p_are[p_ind] = a00 / 2.; p_ind++; a00 = 0; sk1 = 0; x0 = xi; y0 = yi; dxy = 0; } else { /* define intersection point */ dv = yi - yi_1; du = xi - xi_1; dx = ny; dy = -nx; if( fabs( du ) > eps ) t = ((yi_1 - pt_s.y) * du + dv * (pt_s.x - xi_1)) / (du * dy - dx * dv); else t = (xi_1 - pt_s.x) / dx; if( t > eps && t < 1 - eps ) { x_s = pt_s.x + t * dx; y_s = pt_s.y + t * dy; dxy = xi_1 * y_s - x_s * yi_1; a00 += dxy; dxy = x_s * y0 - x0 * y_s; a00 += dxy; if( p_ind >= p_max ) icvMemCopy( &p_are1, &p_are2, &p_are, &p_max ); p_are[p_ind] = a00 / 2.; p_ind++; a00 = 0; sk1 = 0; x0 = x_s; y0 = y_s; dxy = x_s * yi - xi * y_s; } } } else dxy = xi_1 * yi - xi * yi_1; a00 += dxy; xi_1 = xi; yi_1 = yi; sk1 = sk; } } xi = x0; yi = y0; dxy = xi_1 * yi - xi * yi_1; a00 += dxy; if( p_ind >= p_max ) icvMemCopy( &p_are1, &p_are2, &p_are, &p_max ); p_are[p_ind] = a00 / 2.; p_ind++; // common area calculation area = 0; for( i = 0; i < p_ind; i++ ) area += fabs( p_are[i] ); if( p_are1 != NULL ) cvFree( &p_are1 ); else if( p_are2 != NULL ) cvFree( &p_are2 ); return area; }
MV_VOID mvOsIoCachedFree( MV_VOID* pDev, int size, MV_U32 phyAddr, MV_VOID* pVirtAddr ) { cvFree(pVirtAddr); }
/*F/////////////////////////////////////////////////////////////////////////////////////// // Name: icvCalcPGH // Purpose: // Calculates PGH(pairwise geometric histogram) for contour given. // Context: // Parameters: // contour - pointer to input contour object. // pgh - output histogram // ang_dim - number of angle bins (vertical size of histogram) // dist_dim - number of distance bins (horizontal size of histogram) // Returns: // CV_OK or error code // Notes: //F*/ static CvStatus icvCalcPGH( const CvSeq * contour, float *pgh, int angle_dim, int dist_dim ) { char local_buffer[(1 << 14) + 32]; float *local_buffer_ptr = (float *)cvAlignPtr(local_buffer,32); float *buffer = local_buffer_ptr; double angle_scale = (angle_dim - 0.51) / icv_acos_table[0]; double dist_scale = DBL_EPSILON; int buffer_size; int i, count, pass; int *pghi = (int *) pgh; int hist_size = angle_dim * dist_dim; CvSeqReader reader1, reader2; /* external and internal readers */ if( !contour || !pgh ) return CV_NULLPTR_ERR; if( angle_dim <= 0 || angle_dim > 180 || dist_dim <= 0 ) return CV_BADRANGE_ERR; if( !CV_IS_SEQ_POINT_SET( contour )) return CV_BADFLAG_ERR; memset( pgh, 0, hist_size * sizeof( pgh[0] )); count = contour->total; /* allocate buffer for distances */ buffer_size = count * sizeof( float ); if( buffer_size > (int)sizeof(local_buffer) - 32 ) { buffer = (float *) cvAlloc( buffer_size ); if( !buffer ) return CV_OUTOFMEM_ERR; } cvStartReadSeq( contour, &reader1, 0 ); cvStartReadSeq( contour, &reader2, 0 ); /* calc & store squared edge lengths, calculate maximal distance between edges */ for( i = 0; i < count; i++ ) { CvPoint pt1, pt2; double dx, dy; CV_READ_EDGE( pt1, pt2, reader1 ); dx = pt2.x - pt1.x; dy = pt2.y - pt1.y; buffer[i] = (float)(1./sqrt(dx * dx + dy * dy)); } /* do 2 passes. First calculates maximal distance. Second calculates histogram itself. */ for( pass = 1; pass <= 2; pass++ ) { double dist_coeff = 0, angle_coeff = 0; /* run external loop */ for( i = 0; i < count; i++ ) { CvPoint pt1, pt2; int dx, dy; int dist = 0; CV_READ_EDGE( pt1, pt2, reader1 ); dx = pt2.x - pt1.x; dy = pt2.y - pt1.y; if( (dx | dy) != 0 ) { int j; if( pass == 2 ) { dist_coeff = buffer[i] * dist_scale; angle_coeff = buffer[i] * (_CV_ACOS_TABLE_SIZE / 2); } /* run internal loop (for current edge) */ for( j = 0; j < count; j++ ) { CvPoint pt3, pt4; CV_READ_EDGE( pt3, pt4, reader2 ); if( i != j ) /* process edge pair */ { int d1 = (pt3.y - pt1.y) * dx - (pt3.x - pt1.x) * dy; int d2 = (pt4.y - pt1.y) * dx - (pt2.x - pt1.x) * dy; int cross_flag; int *hist_row = 0; if( pass == 2 ) { int dp = (pt4.x - pt3.x) * dx + (pt4.y - pt3.y) * dy; dp = cvRound( dp * angle_coeff * buffer[j] ) + (_CV_ACOS_TABLE_SIZE / 2); dp = MAX( dp, 0 ); dp = MIN( dp, _CV_ACOS_TABLE_SIZE - 1 ); hist_row = pghi + dist_dim * cvRound( icv_acos_table[dp] * angle_scale ); d1 = cvRound( d1 * dist_coeff ); d2 = cvRound( d2 * dist_coeff ); } cross_flag = (d1 ^ d2) < 0; d1 = CV_IABS( d1 ); d2 = CV_IABS( d2 ); if( pass == 2 ) { if( d1 >= dist_dim ) d1 = dist_dim - 1; if( d2 >= dist_dim ) d2 = dist_dim - 1; if( !cross_flag ) { if( d1 > d2 ) /* make d1 <= d2 */ { d1 ^= d2; d2 ^= d1; d1 ^= d2; } for( ; d1 <= d2; d1++ ) hist_row[d1]++; } else { for( ; d1 >= 0; d1-- ) hist_row[d1]++; for( ; d2 >= 0; d2-- ) hist_row[d2]++; } } else /* 1st pass */ { d1 = CV_IMAX( d1, d2 ); dist = CV_IMAX( dist, d1 ); } } /* end of processing of edge pair */ } /* end of internal loop */ if( pass == 1 ) { double scale = dist * buffer[i]; dist_scale = MAX( dist_scale, scale ); } } } /* end of external loop */ if( pass == 1 ) { dist_scale = (dist_dim - 0.51) / dist_scale; } } /* end of pass on loops */ /* convert hist to floats */ for( i = 0; i < hist_size; i++ ) { ((float *) pghi)[i] = (float) pghi[i]; } if( buffer != local_buffer_ptr ) cvFree( &buffer ); return CV_OK; }
/* dst = src */ CV_IMPL void cvCopy( const void* srcarr, void* dstarr, const void* maskarr ) { if( CV_IS_SPARSE_MAT(srcarr) && CV_IS_SPARSE_MAT(dstarr)) { CV_Assert( maskarr == 0 ); CvSparseMat* src1 = (CvSparseMat*)srcarr; CvSparseMat* dst1 = (CvSparseMat*)dstarr; CvSparseMatIterator iterator; CvSparseNode* node; dst1->dims = src1->dims; memcpy( dst1->size, src1->size, src1->dims*sizeof(src1->size[0])); dst1->valoffset = src1->valoffset; dst1->idxoffset = src1->idxoffset; cvClearSet( dst1->heap ); if( src1->heap->active_count >= dst1->hashsize*CV_SPARSE_HASH_RATIO ) { cvFree( &dst1->hashtable ); dst1->hashsize = src1->hashsize; dst1->hashtable = (void**)cvAlloc( dst1->hashsize*sizeof(dst1->hashtable[0])); } memset( dst1->hashtable, 0, dst1->hashsize*sizeof(dst1->hashtable[0])); for( node = cvInitSparseMatIterator( src1, &iterator ); node != 0; node = cvGetNextSparseNode( &iterator )) { CvSparseNode* node_copy = (CvSparseNode*)cvSetNew( dst1->heap ); int tabidx = node->hashval & (dst1->hashsize - 1); CV_MEMCPY_AUTO( node_copy, node, dst1->heap->elem_size ); node_copy->next = (CvSparseNode*)dst1->hashtable[tabidx]; dst1->hashtable[tabidx] = node_copy; } return; } cv::Mat src = cv::cvarrToMat(srcarr, false, true, 1), dst = cv::cvarrToMat(dstarr, false, true, 1); CV_Assert( src.depth() == dst.depth() && src.size() == dst.size() ); int coi1 = 0, coi2 = 0; if( CV_IS_IMAGE(srcarr) ) coi1 = cvGetImageCOI((const IplImage*)srcarr); if( CV_IS_IMAGE(dstarr) ) coi2 = cvGetImageCOI((const IplImage*)dstarr); if( coi1 || coi2 ) { CV_Assert( (coi1 != 0 || src.channels() == 1) && (coi2 != 0 || dst.channels() == 1) ); int pair[] = { std::max(coi1-1, 0), std::max(coi2-1, 0) }; cv::mixChannels( &src, 1, &dst, 1, pair, 1 ); return; } else CV_Assert( src.channels() == dst.channels() ); if( !maskarr ) src.copyTo(dst); else src.copyTo(dst, cv::cvarrToMat(maskarr)); }
CV_IMPL void cvSVBkSb( const CvArr* warr, const CvArr* uarr, const CvArr* varr, const CvArr* barr, CvArr* xarr, int flags ) { uchar* buffer = 0; int local_alloc = 0; CV_FUNCNAME( "cvSVBkSb" ); __BEGIN__; CvMat wstub, *w = (CvMat*)warr; CvMat bstub, *b = (CvMat*)barr; CvMat xstub, *x = (CvMat*)xarr; CvMat ustub, ustub2, *u = (CvMat*)uarr; CvMat vstub, vstub2, *v = (CvMat*)varr; uchar* tw = 0; int type; int temp_u = 0, temp_v = 0; int u_buf_offset = 0, v_buf_offset = 0, w_buf_offset = 0, t_buf_offset = 0; int buf_size = 0, pix_size; int m, n, nm; int u_rows, u_cols; int v_rows, v_cols; if( !CV_IS_MAT( w )) CV_CALL( w = cvGetMat( w, &wstub )); if( !CV_IS_MAT( u )) CV_CALL( u = cvGetMat( u, &ustub )); if( !CV_IS_MAT( v )) CV_CALL( v = cvGetMat( v, &vstub )); if( !CV_IS_MAT( x )) CV_CALL( x = cvGetMat( x, &xstub )); if( !CV_ARE_TYPES_EQ( w, u ) || !CV_ARE_TYPES_EQ( w, v ) || !CV_ARE_TYPES_EQ( w, x )) CV_ERROR( CV_StsUnmatchedFormats, "All matrices must have the same type" ); type = CV_MAT_TYPE( w->type ); pix_size = CV_ELEM_SIZE(type); if( !(flags & CV_SVD_U_T) ) { temp_u = 1; u_buf_offset = buf_size; buf_size += u->cols*u->rows*pix_size; u_rows = u->rows; u_cols = u->cols; } else { u_rows = u->cols; u_cols = u->rows; } if( !(flags & CV_SVD_V_T) ) { temp_v = 1; v_buf_offset = buf_size; buf_size += v->cols*v->rows*pix_size; v_rows = v->rows; v_cols = v->cols; } else { v_rows = v->cols; v_cols = v->rows; } m = u_rows; n = v_rows; nm = MIN(n,m); if( (u_rows != u_cols && v_rows != v_cols) || x->rows != v_rows ) CV_ERROR( CV_StsBadSize, "V or U matrix must be square" ); if( (w->rows == 1 || w->cols == 1) && w->rows + w->cols - 1 == nm ) { if( CV_IS_MAT_CONT(w->type) ) tw = w->data.ptr; else { w_buf_offset = buf_size; buf_size += nm*pix_size; } } else { if( w->cols != v_cols || w->rows != u_cols ) CV_ERROR( CV_StsBadSize, "W must be 1d array of MIN(m,n) elements or " "matrix which size matches to U and V" ); w_buf_offset = buf_size; buf_size += nm*pix_size; } if( b ) { if( !CV_IS_MAT( b )) CV_CALL( b = cvGetMat( b, &bstub )); if( !CV_ARE_TYPES_EQ( w, b )) CV_ERROR( CV_StsUnmatchedFormats, "All matrices must have the same type" ); if( b->cols != x->cols || b->rows != m ) CV_ERROR( CV_StsUnmatchedSizes, "b matrix must have (m x x->cols) size" ); } else { b = &bstub; memset( b, 0, sizeof(*b)); } t_buf_offset = buf_size; buf_size += (MAX(m,n) + b->cols)*pix_size; if( buf_size <= CV_MAX_LOCAL_SIZE ) { buffer = (uchar*)cvStackAlloc( buf_size ); local_alloc = 1; } else CV_CALL( buffer = (uchar*)cvAlloc( buf_size )); if( temp_u ) { cvInitMatHeader( &ustub2, u_cols, u_rows, type, buffer + u_buf_offset ); cvT( u, &ustub2 ); u = &ustub2; } if( temp_v ) { cvInitMatHeader( &vstub2, v_cols, v_rows, type, buffer + v_buf_offset ); cvT( v, &vstub2 ); v = &vstub2; } if( !tw ) { int i, shift = w->cols > 1 ? pix_size : 0; tw = buffer + w_buf_offset; for( i = 0; i < nm; i++ ) memcpy( tw + i*pix_size, w->data.ptr + i*(w->step + shift), pix_size ); } if( type == CV_32FC1 ) { icvSVBkSb_32f( m, n, (float*)tw, u->data.fl, u->step/sizeof(float), v->data.fl, v->step/sizeof(float), b->data.fl, b->step/sizeof(float), b->cols, x->data.fl, x->step/sizeof(float), (float*)(buffer + t_buf_offset) ); } else if( type == CV_64FC1 ) { icvSVBkSb_64f( m, n, (double*)tw, u->data.db, u->step/sizeof(double), v->data.db, v->step/sizeof(double), b->data.db, b->step/sizeof(double), b->cols, x->data.db, x->step/sizeof(double), (double*)(buffer + t_buf_offset) ); } else { CV_ERROR( CV_StsUnsupportedFormat, "" ); } __END__; if( buffer && !local_alloc ) cvFree( &buffer ); }
CV_IMPL void cvSVD( CvArr* aarr, CvArr* warr, CvArr* uarr, CvArr* varr, int flags ) { uchar* buffer = 0; int local_alloc = 0; CV_FUNCNAME( "cvSVD" ); __BEGIN__; CvMat astub, *a = (CvMat*)aarr; CvMat wstub, *w = (CvMat*)warr; CvMat ustub, *u; CvMat vstub, *v; CvMat tmat; uchar* tw = 0; int type; int a_buf_offset = 0, u_buf_offset = 0, buf_size, pix_size; int temp_u = 0, /* temporary storage for U is needed */ t_svd; /* special case: a->rows < a->cols */ int m, n; int w_rows, w_cols; int u_rows = 0, u_cols = 0; int w_is_mat = 0; if( !CV_IS_MAT( a )) CV_CALL( a = cvGetMat( a, &astub )); if( !CV_IS_MAT( w )) CV_CALL( w = cvGetMat( w, &wstub )); if( !CV_ARE_TYPES_EQ( a, w )) CV_ERROR( CV_StsUnmatchedFormats, "" ); if( a->rows >= a->cols ) { m = a->rows; n = a->cols; w_rows = w->rows; w_cols = w->cols; t_svd = 0; } else { CvArr* t; CV_SWAP( uarr, varr, t ); flags = (flags & CV_SVD_U_T ? CV_SVD_V_T : 0)| (flags & CV_SVD_V_T ? CV_SVD_U_T : 0); m = a->cols; n = a->rows; w_rows = w->cols; w_cols = w->rows; t_svd = 1; } u = (CvMat*)uarr; v = (CvMat*)varr; w_is_mat = w_cols > 1 && w_rows > 1; if( !w_is_mat && CV_IS_MAT_CONT(w->type) && w_cols + w_rows - 1 == n ) tw = w->data.ptr; if( u ) { if( !CV_IS_MAT( u )) CV_CALL( u = cvGetMat( u, &ustub )); if( !(flags & CV_SVD_U_T) ) { u_rows = u->rows; u_cols = u->cols; } else { u_rows = u->cols; u_cols = u->rows; } if( !CV_ARE_TYPES_EQ( a, u )) CV_ERROR( CV_StsUnmatchedFormats, "" ); if( u_rows != m || (u_cols != m && u_cols != n)) CV_ERROR( CV_StsUnmatchedSizes, !t_svd ? "U matrix has unappropriate size" : "V matrix has unappropriate size" ); temp_u = (u_rows != u_cols && !(flags & CV_SVD_U_T)) || u->data.ptr==a->data.ptr; if( w_is_mat && u_cols != w_rows ) CV_ERROR( CV_StsUnmatchedSizes, !t_svd ? "U and W have incompatible sizes" : "V and W have incompatible sizes" ); } else { u = &ustub; u->data.ptr = 0; u->step = 0; } if( v ) { int v_rows, v_cols; if( !CV_IS_MAT( v )) CV_CALL( v = cvGetMat( v, &vstub )); if( !(flags & CV_SVD_V_T) ) { v_rows = v->rows; v_cols = v->cols; } else { v_rows = v->cols; v_cols = v->rows; } if( !CV_ARE_TYPES_EQ( a, v )) CV_ERROR( CV_StsUnmatchedFormats, "" ); if( v_rows != n || v_cols != n ) CV_ERROR( CV_StsUnmatchedSizes, t_svd ? "U matrix has unappropriate size" : "V matrix has unappropriate size" ); if( w_is_mat && w_cols != v_cols ) CV_ERROR( CV_StsUnmatchedSizes, t_svd ? "U and W have incompatible sizes" : "V and W have incompatible sizes" ); } else { v = &vstub; v->data.ptr = 0; v->step = 0; } type = CV_MAT_TYPE( a->type ); pix_size = CV_ELEM_SIZE(type); buf_size = n*2 + m; if( !(flags & CV_SVD_MODIFY_A) ) { a_buf_offset = buf_size; buf_size += a->rows*a->cols; } if( temp_u ) { u_buf_offset = buf_size; buf_size += u->rows*u->cols; } buf_size *= pix_size; if( buf_size <= CV_MAX_LOCAL_SIZE ) { buffer = (uchar*)cvStackAlloc( buf_size ); local_alloc = 1; } else { CV_CALL( buffer = (uchar*)cvAlloc( buf_size )); } if( !(flags & CV_SVD_MODIFY_A) ) { cvInitMatHeader( &tmat, m, n, type, buffer + a_buf_offset*pix_size ); if( !t_svd ) cvCopy( a, &tmat ); else cvT( a, &tmat ); a = &tmat; } if( temp_u ) { cvInitMatHeader( &ustub, u_cols, u_rows, type, buffer + u_buf_offset*pix_size ); u = &ustub; } if( !tw ) tw = buffer + (n + m)*pix_size; if( type == CV_32FC1 ) { icvSVD_32f( a->data.fl, a->step/sizeof(float), a->rows, a->cols, (float*)tw, u->data.fl, u->step/sizeof(float), u_cols, v->data.fl, v->step/sizeof(float), (float*)buffer ); } else if( type == CV_64FC1 ) { icvSVD_64f( a->data.db, a->step/sizeof(double), a->rows, a->cols, (double*)tw, u->data.db, u->step/sizeof(double), u_cols, v->data.db, v->step/sizeof(double), (double*)buffer ); } else { CV_ERROR( CV_StsUnsupportedFormat, "" ); } if( tw != w->data.ptr ) { int shift = w->cols != 1; cvSetZero( w ); if( type == CV_32FC1 ) for( int i = 0; i < n; i++ ) ((float*)(w->data.ptr + i*w->step))[i*shift] = ((float*)tw)[i]; else for( int i = 0; i < n; i++ ) ((double*)(w->data.ptr + i*w->step))[i*shift] = ((double*)tw)[i]; } if( uarr ) { if( !(flags & CV_SVD_U_T)) cvT( u, uarr ); else if( temp_u ) cvCopy( u, uarr ); /*CV_CHECK_NANS( uarr );*/ } if( varr ) { if( !(flags & CV_SVD_V_T)) cvT( v, varr ); /*CV_CHECK_NANS( varr );*/ } CV_CHECK_NANS( w ); __END__; if( buffer && !local_alloc ) cvFree( &buffer ); }
~CvPriorityQueueFloat(void) { cvFree( &mem ); }
int opticaltri( CvMat * &clean_texture, int verts ) { char * im1fname = "conhull-dirty-thresh.jpg"; char * im2fname = "conhull-clean-thresh.jpg"; int count = MAX_COUNT; char * status; CvPoint2D32f * source_points; CvPoint2D32f * dest_points; CvPoint2D32f * delaunay_points = (CvPoint2D32f*)cvAlloc(MAX_COUNT*sizeof(CvPoint2D32f)); // count = opticalflow( im1fname, im2fname, source_points, dest_points, status ); count = findsiftpoints( "conhull-dirty.jpg", "conhull-clean.jpg", source_points, dest_points, status ); IplImage * image1 = cvLoadImage(im1fname, CV_LOAD_IMAGE_COLOR); CvMemStorage * storage = cvCreateMemStorage(0); CvSubdiv2D * delaunay = cvCreateSubdivDelaunay2D( cvRect(0,0,image1->width,image1->height), storage); IplImage * image2 = cvLoadImage(im2fname, CV_LOAD_IMAGE_COLOR); cvSet( image1, cvScalarAll(255) ); std::map<CvPoint, CvPoint> point_lookup_map; std::vector<std::pair<CvPoint, CvPoint> > point_lookup; int num_matches = 0; int num_out_matches = 0; int max_dist = 50; int offset = 200; // put corners in the point lookup as going to themselves point_lookup_map[cvPoint(0,0)] = cvPoint(0,0); point_lookup_map[cvPoint(0,image1->height-1)] = cvPoint(0,image1->height-1); point_lookup_map[cvPoint(image1->width-1,0)] = cvPoint(image1->width-1,0); point_lookup_map[cvPoint(image1->width-1,image1->height-1)] = cvPoint(image1->width-1,image1->height-1); point_lookup.push_back(std::pair<CvPoint,CvPoint>(cvPoint(0,0), cvPoint(0,0))); point_lookup.push_back(std::pair<CvPoint,CvPoint>(cvPoint(0,image1->height-1), cvPoint(0,image1->height-1))); point_lookup.push_back(std::pair<CvPoint,CvPoint>(cvPoint(image1->width-1,0), cvPoint(image1->width-1,0))); point_lookup.push_back(std::pair<CvPoint,CvPoint>(cvPoint(image1->width-1,image1->height-1), cvPoint(image1->width-1,image1->height-1))); printf("Inserting corners..."); // put corners in the Delaunay subdivision for(unsigned int i = 0; i < point_lookup.size(); i++) { cvSubdivDelaunay2DInsert( delaunay, cvPointTo32f(point_lookup[i].first) ); } printf("done.\n"); CvSubdiv2DEdge proxy_edge; for(int i = 0; i < count; i++) { if(status[i]) { CvPoint source = cvPointFrom32f(source_points[i]); CvPoint dest = cvPointFrom32f(dest_points[i]); if((((int)fabs((double)(source.x - dest.x))) > max_dist) || (((int)fabs((double)(source.y - dest.y))) > max_dist)) { num_out_matches++; } else if((dest.x >= 0) && (dest.y >= 0) && (dest.x < (image1->width)) && (dest.y < (image1->height))) { if(point_lookup_map.find(source) == point_lookup_map.end()) { num_matches++; point_lookup_map[source] = dest; point_lookup.push_back(std::pair<CvPoint,CvPoint>(source,dest)); // delaunay_points[i] = (cvSubdivDelaunay2DInsert( delaunay, cvPointTo32f(source) ))->pt; cvSetImageROI( image1, cvRect(source.x-8,source.y-8,8*2,8*2) ); cvResetImageROI( image2 ); cvGetRectSubPix( image2, image1, dest_points[i] ); } /* cvSet2D( image1, source.y, source.x, cvGet2D( image2, dest.y, dest.x ) ); cvSet2D( image1, source.y, source.x+1, cvGet2D( image2, dest.y, dest.x+1 ) ); cvSet2D( image1, source.y, source.x-1, cvGet2D( image2, dest.y, dest.x-1 ) ); cvSet2D( image1, source.y+1, source.x, cvGet2D( image2, dest.y+1, dest.x ) ); cvSet2D( image1, source.y-1, source.x, cvGet2D( image2, dest.y-1, dest.x ) ); cvSet2D( image1, source.y+1, source.x+1, cvGet2D( image2, dest.y+1, dest.x+1 ) ); cvSet2D( image1, source.y-1, source.x-1, cvGet2D( image2, dest.y-1, dest.x-1 ) ); cvSet2D( image1, source.y+1, source.x-1, cvGet2D( image2, dest.y+1, dest.x-1 ) ); cvSet2D( image1, source.y-1, source.x+1, cvGet2D( image2, dest.y-1, dest.x+1 ) ); */ // cvCircle( image1, source, 4, CV_RGB(255,0,0), 2, CV_AA ); // cvCircle( image2, dest, 4, CV_RGB(255,0,0), 2, CV_AA ); } /* cvSetImageROI( image1, cvRect(source.x-offset,source.y-offset,offset*2,offset*2) ); cvSetImageROI( image2, cvRect(dest.x-offset,dest.y-offset,offset*2,offset*2) ); cvNamedWindow("image1",0); cvNamedWindow("image2",0); cvShowImage("image1",image1); cvShowImage("image2",image2); printf("%d,%d -> %d,%d\n",source.x,source.y,dest.x,dest.y); cvWaitKey(0); cvDestroyAllWindows(); */ } } printf("%d %d\n",num_matches,num_out_matches); printf("%d lookups\n",point_lookup_map.size()); cvResetImageROI( image1 ); cvSaveImage("sparse.jpg", image1); cvReleaseImage(&image1); image1 = cvLoadImage(im1fname, CV_LOAD_IMAGE_COLOR); cvSet( image1, cvScalarAll(255) ); printf("Warping image..."); CvSeqReader reader; int total = delaunay->edges->total; int elem_size = delaunay->edges->elem_size; std::vector<Triangle> trivec; std::vector<CvMat *> baryinvvec; for( int i = 0; i < total*2; i++ ) { if((i == 0) || (i == total)) { cvStartReadSeq( (CvSeq*)(delaunay->edges), &reader, 0 ); } CvQuadEdge2D* edge = (CvQuadEdge2D*)(reader.ptr); if( CV_IS_SET_ELEM( edge )) { CvSubdiv2DEdge curedge = (CvSubdiv2DEdge)edge; CvSubdiv2DEdge t = curedge; Triangle temptri; int count = 0; // construct a triangle from this edge do { CvSubdiv2DPoint* pt = cvSubdiv2DEdgeOrg( t ); if(count < 3) { pt->pt.x = pt->pt.x >= image1->width ? image1->width-1 : pt->pt.x; pt->pt.y = pt->pt.y >= image1->height ? image1->height-1 : pt->pt.y; pt->pt.x = pt->pt.x < 0 ? 0 : pt->pt.x; pt->pt.y = pt->pt.y < 0 ? 0 : pt->pt.y; temptri.points[count] = cvPointFrom32f( pt->pt ); } else { printf("More than 3 edges\n"); } count++; if(i < total) t = cvSubdiv2DGetEdge( t, CV_NEXT_AROUND_LEFT ); else t = cvSubdiv2DGetEdge( t, CV_NEXT_AROUND_RIGHT ); } while( t != curedge ); // check that triangle is not already in if( std::find(trivec.begin(), trivec.end(), temptri) == trivec.end() ) { // push triangle in and draw trivec.push_back(temptri); cvLine( image1, temptri.points[0], temptri.points[1], CV_RGB(255,0,0), 1, CV_AA, 0 ); cvLine( image1, temptri.points[1], temptri.points[2], CV_RGB(255,0,0), 1, CV_AA, 0 ); cvLine( image1, temptri.points[2], temptri.points[0], CV_RGB(255,0,0), 1, CV_AA, 0 ); // compute barycentric computation vector for this triangle CvMat * barycen = cvCreateMat( 3, 3, CV_32FC1 ); CvMat * baryceninv = cvCreateMat( 3, 3, CV_32FC1 ); barycen->data.fl[3*0+0] = temptri.points[0].x; barycen->data.fl[3*0+1] = temptri.points[1].x; barycen->data.fl[3*0+2] = temptri.points[2].x; barycen->data.fl[3*1+0] = temptri.points[0].y; barycen->data.fl[3*1+1] = temptri.points[1].y; barycen->data.fl[3*1+2] = temptri.points[2].y; barycen->data.fl[3*2+0] = 1; barycen->data.fl[3*2+1] = 1; barycen->data.fl[3*2+2] = 1; cvInvert( barycen, baryceninv, CV_LU ); baryinvvec.push_back(baryceninv); cvReleaseMat( &barycen ); } } CV_NEXT_SEQ_ELEM( elem_size, reader ); } printf("%d triangles...", trivec.size()); cvSaveImage("triangles.jpg", image1); cvSet( image1, cvScalarAll(255) ); IplImage * clean_nonthresh = cvLoadImage( "conhull-clean.jpg", CV_LOAD_IMAGE_COLOR ); // for each triangle for(unsigned int i = 0; i < trivec.size(); i++) { Triangle curtri = trivec[i]; CvMat * curpoints = cvCreateMat( 1, 3, CV_32SC2 ); Triangle target; std::map<CvPoint,CvPoint>::iterator piter[3]; printf("Triangle %d / %d\n",i,trivec.size()); int is_corner = 0; for(int j = 0; j < 3; j++) { /* curpoints->data.i[2*j+0] = curtri.points[j].x; curpoints->data.i[2*j+1] = curtri.points[j].y; */ CV_MAT_ELEM( *curpoints, CvPoint, 0, j ) = curtri.points[j]; printf("%d,%d\n",curtri.points[j].x,curtri.points[j].y); if((curtri.points[j] == cvPoint(0,0)) || (curtri.points[j] == cvPoint(0,image1->height - 1)) ||(curtri.points[j] == cvPoint(image1->width - 1,0)) ||(curtri.points[j] == cvPoint(image1->width - 1,image1->height - 1))) { is_corner++; } for(unsigned int k = 0; k < point_lookup.size(); k++) { std::pair<CvPoint,CvPoint> thispair = point_lookup[k]; if(thispair.first == curtri.points[j]) { target.points[j] = thispair.second; break; } } /* piter[j] = point_lookup_map.find(curtri.points[j]); if(piter[j] != point_lookup_map.end() ) { target.points[j] = piter[j]->second; } */ } // if((piter[0] != point_lookup_map.end()) && (piter[1] != point_lookup_map.end()) && (piter[2] != point_lookup_map.end())) { if(is_corner < 3) { CvMat * newcorners = cvCreateMat( 3, 3, CV_32FC1 ); newcorners->data.fl[3*0+0] = target.points[0].x; newcorners->data.fl[3*0+1] = target.points[1].x; newcorners->data.fl[3*0+2] = target.points[2].x; newcorners->data.fl[3*1+0] = target.points[0].y; newcorners->data.fl[3*1+1] = target.points[1].y; newcorners->data.fl[3*1+2] = target.points[2].y; newcorners->data.fl[3*2+0] = 1; newcorners->data.fl[3*2+1] = 1; newcorners->data.fl[3*2+2] = 1; CvContour hdr; CvSeqBlock blk; CvRect trianglebound = cvBoundingRect( cvPointSeqFromMat(CV_SEQ_KIND_CURVE+CV_SEQ_FLAG_CLOSED, curpoints, &hdr, &blk), 1 ); printf("Bounding box: %d,%d,%d,%d\n",trianglebound.x,trianglebound.y,trianglebound.width,trianglebound.height); for(int y = trianglebound.y; (y < (trianglebound.y + trianglebound.height)) && ( y < image1->height); y++) { for(int x = trianglebound.x; (x < (trianglebound.x + trianglebound.width)) && (x < image1->width); x++) { // check to see if we're inside this triangle /* CvPoint v0 = cvPoint( curtri.points[2].x - curtri.points[0].x, curtri.points[2].y - curtri.points[0].y ); CvPoint v1 = cvPoint( curtri.points[1].x - curtri.points[0].x, curtri.points[1].y - curtri.points[0].y ); CvPoint v2 = cvPoint( x - curtri.points[0].x, y - curtri.points[0].y ); int dot00 = v0.x * v0.x + v0.y * v0. y; int dot01 = v0.x * v1.x + v0.y * v1. y; int dot02 = v0.x * v2.x + v0.y * v2. y; int dot11 = v1.x * v1.x + v1.y * v1. y; int dot12 = v1.x * v2.x + v1.y * v2. y; double invDenom = 1.0 / (double)(dot00 * dot11 - dot01 * dot01); double u = (double)(dot11 * dot02 - dot01 * dot12) * invDenom; double v = (double)(dot00 * dot12 - dot01 * dot02) * invDenom; */ CvMat * curp = cvCreateMat(3, 1, CV_32FC1); CvMat * result = cvCreateMat(3, 1, CV_32FC1); curp->data.fl[0] = x; curp->data.fl[1] = y; curp->data.fl[2] = 1; cvMatMul( baryinvvec[i], curp, result ); // double u = result->data.fl[0]/result->data.fl[2]; // double v = result->data.fl[1]/result->data.fl[2]; /* if((i == 3019) && (y == 1329) && (x > 2505) && (x < 2584)) { printf("Range %d: %f, %f, %f\t%f, %f, %f\n",x,result->data.fl[0],result->data.fl[1],result->data.fl[2], sourcepoint->data.fl[0],sourcepoint->data.fl[1],sourcepoint->data.fl[2]); } */ if( (result->data.fl[0] > MIN_VAL) && (result->data.fl[1] > MIN_VAL) && (result->data.fl[2] > MIN_VAL) && (fabs(1.0 - (result->data.fl[0]+result->data.fl[1]+result->data.fl[2])) <= 0.01) ) { // if((u > 0) || (v > 0) /*&& ((u +v) < 1)*/ ) // printf("Barycentric: %f %f %f\n", result->data.fl[0], result->data.fl[1], result->data.fl[2]); // this point is inside this triangle // printf("Point %d,%d inside %d,%d %d,%d %d,%d\n",x,y,trivec[i].points[0].x,trivec[i].points[0].y, // trivec[i].points[1].x,trivec[i].points[1].y,trivec[i].points[2].x,trivec[i].points[2].y); CvMat * sourcepoint = cvCreateMat(3, 1, CV_32FC1); cvMatMul( newcorners, result, sourcepoint ); double sourcex = sourcepoint->data.fl[0]/*/sourcepoint->data.fl[2]*/; double sourcey = sourcepoint->data.fl[1]/*/sourcepoint->data.fl[2]*/; if((sourcex >= 0) && (sourcey >= 0) && (sourcex < (image1->width)) && (sourcey < (image1->height))) { // printf("%d,%d %d,%d\n",x,y,(int)sourcex,(int)sourcey); cvSet2D( image1, y, x, cvGet2D( clean_nonthresh, (int)sourcey, (int)sourcex ) ); } // printf("Point %d,%d inside %d,%d %d,%d %d,%d\n",x,y,trivec[i].points[0].x,trivec[i].points[0].y, // trivec[i].points[1].x,trivec[i].points[1].y,trivec[i].points[2].x,trivec[i].points[2].y); cvReleaseMat( &sourcepoint ); } cvReleaseMat( &result ); cvReleaseMat( &curp ); } } for(int k = 0; k < verts; k++) { double x = clean_texture->data.fl[2*k+0]; double y = clean_texture->data.fl[2*k+1]; // check to see if we're inside this triangle CvMat * curp = cvCreateMat(3, 1, CV_32FC1); CvMat * result = cvCreateMat(3, 1, CV_32FC1); curp->data.fl[0] = x; curp->data.fl[1] = y; curp->data.fl[2] = 1; cvMatMul( baryinvvec[i], curp, result ); if( (result->data.fl[0] > MIN_VAL) && (result->data.fl[1] > MIN_VAL) && (result->data.fl[2] > MIN_VAL) && (fabs(1.0 - (result->data.fl[0]+result->data.fl[1]+result->data.fl[2])) <= 0.01) ) { CvMat * sourcepoint = cvCreateMat(3, 1, CV_32FC1); cvMatMul( newcorners, result, sourcepoint ); double sourcex = sourcepoint->data.fl[0]/*/sourcepoint->data.fl[2]*/; double sourcey = sourcepoint->data.fl[1]/*/sourcepoint->data.fl[2]*/; if((sourcex >= 0) && (sourcey >= 0) && (sourcex < (image1->width)) && (sourcey < (image1->height))) { clean_texture->data.fl[2*k+0] = sourcex; clean_texture->data.fl[2*k+1] = sourcey; // cvSet2D( image1, y, x, cvGet2D( clean_nonthresh, (int)sourcey, (int)sourcex ) ); } cvReleaseMat( &sourcepoint ); } cvReleaseMat( &result ); cvReleaseMat( &curp ); } cvReleaseMat( &newcorners ); } cvReleaseMat( &curpoints ); } cvReleaseImage( &clean_nonthresh ); printf("done.\n"); cvSaveImage("fullwarp.jpg", image1); printf("Drawing subdivisions on warped image..."); draw_subdiv( image1, delaunay, NULL, NULL, 0, NULL ); // draw_subdiv( image1, delaunay, delaunay_points, source_points, count, status ); printf("done.\n"); cvSaveImage("edgeswarp.jpg", image1); cvReleaseImage(&image2); image2 = cvLoadImage(im2fname, CV_LOAD_IMAGE_COLOR); // cvCreateImage( cvGetSize(image2), IPL_DEPTH_8U, 3 ); // cvCalcSubdivVoronoi2D( delaunay ); printf("Drawing subdivisions on unwarped image..."); // draw_subdiv( image2, delaunay, delaunay_points, dest_points, count, status ); // draw_subdiv( image2, delaunay, NULL, NULL, 0, NULL ); printf("done.\n"); cvSaveImage("edges.jpg",image2); cvReleaseImage(&image1); cvFree(&source_points); cvFree(&dest_points); cvFree(&status); cvReleaseMemStorage(&storage); cvFree(&delaunay_points); cvReleaseImage(&image2); return 0; }