node_t* kdtree_build(int l, int r, int d) { if(r < l) return 0; int m = (l + r) >> 1; kdtree_dimesion = d; std::nth_element(pt + l, pt + m, pt + r + 1); node_t *n = node + used++; n->p = pt[m]; n->l = kdtree_build(l, m - 1, (d + 1) % 3); n->r = kdtree_build(m + 1, r, (d + 1) % 3); kdtree_update(n); return n; }
int compare_features(FeatureData* f0, FeatureData* f1) { struct kd_node* kd_root; double d0, d1; struct feature** nbrs; int num_matches; size_t i; /* Serves as an index into an array, hence, size_t */ /* Build KD Tree */ kd_root = kdtree_build(f1->features, f1->count); /* Compare feature distances */ for(i = 0; i < f0->count; ++i) { int k; struct feature* feat; feat = f0->features + i; k = kdtree_bbf_knn( kd_root, feat, 2, &nbrs, KDTREE_BBF_MAX_NN_CHKS ); if( k == 2 ) { d0 = descr_dist_sq( feat, nbrs[0] ); d1 = descr_dist_sq( feat, nbrs[1] ); if( d0 < d1 * NN_SQ_DIST_RATIO_THR ) ++num_matches; } free( nbrs ); } kdtree_release( kd_root ); return num_matches; }
int CUtil_Sift::CmpSiftFiles( const char* siftfile,vector< pair<int,string> >& vecDstFiles ) { if ( !siftfile || vecDstFiles.size()<1 ) { return -1; } struct feature* feat1, * feat2, * feat; int n1, n2, k, i, m; int iVec; /////////////////////////////////////////////////////////////// struct feature** nbrs; struct kd_node* kd_root; double d0, d1; n2 = import_features((char*)siftfile,FEATURE_LOWE,&feat2); if(n2<1) { return -1; } fprintf(stderr,"there are %d points in siftfile\n",n2); kd_root = kdtree_build( feat2, n2 ); for ( iVec=0; iVec<(int)vecDstFiles.size(); iVec++ ) { vecDstFiles[iVec].first=0; n1 = import_features((char*)(vecDstFiles[iVec].second.c_str()),FEATURE_LOWE,&feat1); if ( n1<1 ) { continue; } m=0; for( i = 0; i < n1; i++ ) { feat = feat1 + i; k = kdtree_bbf_knn( kd_root, feat, 2, &nbrs, KDTREE_BBF_MAX_NN_CHKS ); if( k == 2 ) { d0 = descr_dist_sq( feat, nbrs[0] ); d1 = descr_dist_sq( feat, nbrs[1] ); if( d0 <= d1 * NN_SQ_DIST_RATIO_THR ) { m++; feat1[i].fwd_match = nbrs[0]; } } free( nbrs ); } fprintf(stderr,"get %d same points\n",m); vecDstFiles[iVec].first = m; free( feat1 ); } kdtree_release( kd_root ); free( feat2 ); sort(vecDstFiles.begin(),vecDstFiles.end(),cmp); return 0; }
int CUtil_Sift::CmpSiftFilesF( const char* siftfile1,const char* siftfile2 ) { if ( !siftfile1 || !siftfile2 ) { return -1; } struct feature* feat1, * feat2, * feat; int n1, n2, k, i, m; /////////////////////////////////////////////////////////////// struct feature** nbrs; struct kd_node* kd_root; double d0, d1; n1 = import_features((char*)siftfile1,FEATURE_LOWE,&feat1); if(n1<1) { return -1; } kd_root = kdtree_build( feat1, n1 ); { n2 = import_features((char*)siftfile2,FEATURE_LOWE,&feat2); if ( n2<1 ) { return -1; } m=0; for( i = 0; i < n2; i++ ) { feat = feat2 + i; k = kdtree_bbf_knn( kd_root, feat, 2, &nbrs, KDTREE_BBF_MAX_NN_CHKS ); if( k == 2 ) { d0 = descr_dist_sq( feat, nbrs[0] ); d1 = descr_dist_sq( feat, nbrs[1] ); if( d0 <= d1 * NN_SQ_DIST_RATIO_THR ) { m++; feat2[i].fwd_match = nbrs[0]; } } free( nbrs ); } free( feat2 ); } kdtree_release( kd_root ); free( feat1 ); return m; }
int main( int argc, char** argv ) { struct feature* feat1, * feat2, * feat; struct feature** nbrs; struct kd_node* kd_root; CvPoint pt1, pt2; double d0, d1; int n1, n2, k, i, m = 0; if( argc != 3 ) fatal_error( "usage: %s <feat_file> <feat_file>", argv[0] ); n1 = import_features( argv[1], feat_type, &feat1 ); if( n1 == -1 ) fatal_error( "unable to import features from %s", argv[1] ); n2 = import_features( argv[2], feat_type, &feat2 ); if( n2 == -1 ) fatal_error( "unable to import features from %s", argv[2] ); kd_root = kdtree_build( feat2, n2 ); for( i = 0; i < n1; i++ ) { feat = feat1 + i; k = kdtree_bbf_knn( kd_root, feat, 2, &nbrs, KDTREE_BBF_MAX_NN_CHKS ); if( k == 2 ) { d0 = descr_dist_sq( feat, nbrs[0] ); d1 = descr_dist_sq( feat, nbrs[1] ); if( d0 < d1 * NN_SQ_DIST_RATIO_THR ) { pt1 = cvPoint( cvRound( feat->x ), cvRound( feat->y ) ); pt2 = cvPoint( cvRound( nbrs[0]->x ), cvRound( nbrs[0]->y ) ); pt2.y += 20; m++; feat1[i].fwd_match = nbrs[0]; } } free( nbrs ); } printf("%d\n", m ); kdtree_release( kd_root ); free( feat1 ); free( feat2 ); return 0; }
void index_file(char *path, void* db_) { GDBM_FILE db = db_; datum key = {path, strlen(path)+1}; int skip; #pragma omp critical skip = gdbm_exists(db, key); if(skip) { free(path); return; } struct feature *features; int num_features; struct kd_node *kd_tree; char *data; size_t data_size; if(verbose) tprintf("%s\n", path); if(!sift(path, &features, &num_features)) { free(path); return; } if(verbose) tprintf(" %d features detected\n", num_features); kd_tree = kdtree_build(features, num_features); pack(features, num_features, kd_tree, &data, &data_size); free(features); kdtree_release(kd_tree); datum value = {data, data_size}; #pragma omp critical gdbm_store(db, key, value, GDBM_REPLACE); free(data); free(path); }
static PyObject* spherematch_kdtree_build(PyObject* self, PyObject* args) { int N, D; int i,j; int Nleaf, treeoptions, treetype; kdtree_t* kd; double* data; PyArrayObject* x; if (!PyArg_ParseTuple(args, "O!", &PyArray_Type, &x)) return NULL; if (PyArray_NDIM(x) != 2) { PyErr_SetString(PyExc_ValueError, "array must be two-dimensional"); return NULL; } if (PyArray_TYPE(x) != PyArray_DOUBLE) { PyErr_SetString(PyExc_ValueError, "array must contain doubles"); return NULL; } N = (int)PyArray_DIM(x, 0); D = (int)PyArray_DIM(x, 1); if (D > 10) { PyErr_SetString(PyExc_ValueError, "maximum dimensionality is 10: maybe you need to transpose your array?"); return NULL; } data = malloc(N * D * sizeof(double)); for (i=0; i<N; i++) { for (j=0; j<D; j++) { double* pd = PyArray_GETPTR2(x, i, j); data[i*D + j] = *pd; } } Nleaf = 16; treetype = KDTT_DOUBLE; //treeoptions = KD_BUILD_SPLIT; treeoptions = KD_BUILD_BBOX; kd = kdtree_build(NULL, data, N, D, Nleaf, treetype, treeoptions); return Py_BuildValue("k", kd); }
static bool parse_scene(t_xml_parser *xml, t_scene *dst) { t_parse_scene scene; scene = (t_parse_scene){DSTR0(), KDTREE_BUILDER(3), VECTOR(t_light), VECTOR(t_camera), DEF_SKY_COLOR}; if (!ft_xml_next(xml) || (xml->token == XML_TOKEN_PARAM && !parse_xml_params(xml, &g_scene_params, &scene))) return (false); while (true) { ASSERT(xml->token == XML_TOKEN_START); if (!parse_scene_child(xml, &scene)) { ft_dstrclear(&scene.name); ft_vclear(&scene.lights); ft_vclear(&scene.cameras); kdtree_builder_destroy(&scene.kdtree); return (false); } if (!ft_xml_next(xml)) break ; } if (xml->token != XML_TOKEN_END) return (ft_xml_error(xml, SUBC("Unexpected EOF"))); if (scene.cameras.length == 0) ft_vpush(&scene.cameras, &DEF_CAMERA, 1); *dst = (t_scene){ DSTR_SUB(scene.name), kdtree_build(&scene.kdtree), scene.lights, scene.cameras, scene.sky_color }; kdtree_builder_destroy(&scene.kdtree); print_kdtree(dst->objs.root, 1, '.'); ft_logf(LOG_VERBOSE, "Scene '%ts' loaded: %u object(s), %u light(s), " "%u camera(s)", dst->name, dst->objs.length, dst->lights.length, dst->cameras.length); return (true); }
int main() { std::scanf("%lld %lld %lld", &n, &range, &seed); for(int i = 0; i != n; ++i) { for(int j = 0; j != 3; ++j) pt[i][j] = get(); } std::sort(pt, pt + n, cmp); n = std::unique(pt, pt + n) - pt; node_t *root = kdtree_build(0, n - 1, 1); for(int i = 0; i != n; ++i) { asked = pt[i]; kdtree_ask(root); } std::printf("%lld\n%lld", ans, count >> 1); return 0; }
//特征匹配 void SiftMatch::on_matchButton_clicked() { //若用户勾选了水平排列按钮 if(ui->radioButton_horizontal->isChecked()) { //将2幅图片合成1幅图片,img1在左,img2在右 stacked = stack_imgs_horizontal(img1, img2);//合成图像,显示经距离比值法筛选后的匹配结果 } else//用户勾选了垂直排列按钮 { verticalStackFlag = true;//垂直排列标识设为true //将2幅图片合成1幅图片,img1在上,img2在下 stacked = stack_imgs( img1, img2 );//合成图像,显示经距离比值法筛选后的匹配结果 } //根据图1的特征点集feat1建立k-d树,返回k-d树根给kd_root kd_root = kdtree_build( feat1, n1 ); Point pt1,pt2;//连线的两个端点 double d0,d1;//feat2中每个特征点到最近邻和次近邻的距离 int matchNum = 0;//经距离比值法筛选后的匹配点对的个数 //遍历特征点集feat2,针对feat2中每个特征点feat,选取符合距离比值条件的匹配点,放到feat的fwd_match域中 for(int i = 0; i < n2; i++ ) { feat = feat2+i;//第i个特征点的指针 //在kd_root中搜索目标点feat的2个最近邻点,存放在nbrs中,返回实际找到的近邻点个数 int k = kdtree_bbf_knn( kd_root, feat, 2, &nbrs, KDTREE_BBF_MAX_NN_CHKS ); if( k == 2 ) { d0 = descr_dist_sq( feat, nbrs[0] );//feat与最近邻点的距离的平方 d1 = descr_dist_sq( feat, nbrs[1] );//feat与次近邻点的距离的平方 //若d0和d1的比值小于阈值NN_SQ_DIST_RATIO_THR,则接受此匹配,否则剔除 if( d0 < d1 * NN_SQ_DIST_RATIO_THR ) { //将目标点feat和最近邻点作为匹配点对 pt2 = Point( cvRound( feat->x ), cvRound( feat->y ) );//图2中点的坐标 pt1 = Point( cvRound( nbrs[0]->x ), cvRound( nbrs[0]->y ) );//图1中点的坐标(feat的最近邻点) if(verticalStackFlag)//垂直排列 pt2.y += img1->height;//由于两幅图是上下排列的,pt2的纵坐标加上图1的高度,作为连线的终点 else pt2.x += img1->width;//由于两幅图是左右排列的,pt2的横坐标加上图1的宽度,作为连线的终点 cvLine( stacked, pt1, pt2, CV_RGB(255,0,255), 1, 8, 0 );//画出连线 matchNum++;//统计匹配点对的个数 feat2[i].fwd_match = nbrs[0];//使点feat的fwd_match域指向其对应的匹配点 } } free( nbrs );//释放近邻数组 } qDebug()<<tr("经距离比值法筛选后的匹配点对个数:")<<matchNum<<endl; //显示并保存经距离比值法筛选后的匹配图 //cvNamedWindow(IMG_MATCH1);//创建窗口 //cvShowImage(IMG_MATCH1,stacked);//显示 //保存匹配图 QString name_match_DistRatio = name1;//文件名,原文件名去掉序号后加"_match_DistRatio" cvSaveImage(name_match_DistRatio.replace( name_match_DistRatio.lastIndexOf(".",-1)-1 , 1 , "_match_DistRatio").toAscii().data(),stacked); //利用RANSAC算法筛选匹配点,计算变换矩阵H, //无论img1和img2的左右顺序,H永远是将feat2中的特征点变换为其匹配点,即将img2中的点变换为img1中的对应点 H = ransac_xform(feat2,n2,FEATURE_FWD_MATCH,lsq_homog,4,0.01,homog_xfer_err,3.0,&inliers,&n_inliers); //若能成功计算出变换矩阵,即两幅图中有共同区域 if( H ) { qDebug()<<tr("经RANSAC算法筛选后的匹配点对个数:")<<n_inliers<<endl; // //输出H矩阵 // for(int i=0;i<3;i++) // qDebug()<<cvmGet(H,i,0)<<cvmGet(H,i,1)<<cvmGet(H,i,2); if(verticalStackFlag)//将2幅图片合成1幅图片,img1在上,img2在下 stacked_ransac = stack_imgs( img1, img2 );//合成图像,显示经RANSAC算法筛选后的匹配结果 else//将2幅图片合成1幅图片,img1在左,img2在右 stacked_ransac = stack_imgs_horizontal(img1, img2);//合成图像,显示经RANSAC算法筛选后的匹配结果 //img1LeftBound = inliers[0]->fwd_match->x;//图1中匹配点外接矩形的左边界 //img1RightBound = img1LeftBound;//图1中匹配点外接矩形的右边界 //img2LeftBound = inliers[0]->x;//图2中匹配点外接矩形的左边界 //img2RightBound = img2LeftBound;//图2中匹配点外接矩形的右边界 int invertNum = 0;//统计pt2.x > pt1.x的匹配点对的个数,来判断img1中是否右图 //遍历经RANSAC算法筛选后的特征点集合inliers,找到每个特征点的匹配点,画出连线 for(int i=0; i<n_inliers; i++) { feat = inliers[i];//第i个特征点 pt2 = Point(cvRound(feat->x), cvRound(feat->y));//图2中点的坐标 pt1 = Point(cvRound(feat->fwd_match->x), cvRound(feat->fwd_match->y));//图1中点的坐标(feat的匹配点) //qDebug()<<"pt2:("<<pt2.x<<","<<pt2.y<<")--->pt1:("<<pt1.x<<","<<pt1.y<<")";//输出对应点对 /*找匹配点区域的边界 if(pt1.x < img1LeftBound) img1LeftBound = pt1.x; if(pt1.x > img1RightBound) img1RightBound = pt1.x; if(pt2.x < img2LeftBound) img2LeftBound = pt2.x; if(pt2.x > img2RightBound) img2RightBound = pt2.x;//*/ //统计匹配点的左右位置关系,来判断图1和图2的左右位置关系 if(pt2.x > pt1.x) invertNum++; if(verticalStackFlag)//垂直排列 pt2.y += img1->height;//由于两幅图是上下排列的,pt2的纵坐标加上图1的高度,作为连线的终点 else//水平排列 pt2.x += img1->width;//由于两幅图是左右排列的,pt2的横坐标加上图1的宽度,作为连线的终点 cvLine(stacked_ransac,pt1,pt2,CV_RGB(255,0,255),1,8,0);//在匹配图上画出连线 } //绘制图1中包围匹配点的矩形 //cvRectangle(stacked_ransac,cvPoint(img1LeftBound,0),cvPoint(img1RightBound,img1->height),CV_RGB(0,255,0),2); //绘制图2中包围匹配点的矩形 //cvRectangle(stacked_ransac,cvPoint(img1->width+img2LeftBound,0),cvPoint(img1->width+img2RightBound,img2->height),CV_RGB(0,0,255),2); //cvNamedWindow(IMG_MATCH2);//创建窗口 //cvShowImage(IMG_MATCH2,stacked_ransac);//显示经RANSAC算法筛选后的匹配图 //保存匹配图 QString name_match_RANSAC = name1;//文件名,原文件名去掉序号后加"_match_RANSAC" cvSaveImage(name_match_RANSAC.replace( name_match_RANSAC.lastIndexOf(".",-1)-1 , 1 , "_match_RANSAC").toAscii().data(),stacked_ransac); /*程序中计算出的变换矩阵H用来将img2中的点变换为img1中的点,正常情况下img1应该是左图,img2应该是右图。 此时img2中的点pt2和img1中的对应点pt1的x坐标的关系基本都是:pt2.x < pt1.x 若用户打开的img1是右图,img2是左图,则img2中的点pt2和img1中的对应点pt1的x坐标的关系基本都是:pt2.x > pt1.x 所以通过统计对应点变换前后x坐标大小关系,可以知道img1是不是右图。 如果img1是右图,将img1中的匹配点经H的逆阵H_IVT变换后可得到img2中的匹配点*/ //若pt2.x > pt1.x的点的个数大于内点个数的80%,则认定img1中是右图 if(invertNum > n_inliers * 0.8) { qDebug()<<tr("img1中是右图"); CvMat * H_IVT = cvCreateMat(3, 3, CV_64FC1);//变换矩阵的逆矩阵 //求H的逆阵H_IVT时,若成功求出,返回非零值 if( cvInvert(H,H_IVT) ) { // //输出H_IVT // for(int i=0;i<3;i++) // qDebug()<<cvmGet(H_IVT,i,0)<<cvmGet(H_IVT,i,1)<<cvmGet(H_IVT,i,2); cvReleaseMat(&H);//释放变换矩阵H,因为用不到了 H = cvCloneMat(H_IVT);//将H的逆阵H_IVT中的数据拷贝到H中 cvReleaseMat(&H_IVT);//释放逆阵H_IVT //将img1和img2对调 IplImage * temp = img2; img2 = img1; img1 = temp; //cvShowImage(IMG1,img1); //cvShowImage(IMG2,img2); ui->mosaicButton->setEnabled(true);//激活全景拼接按钮 } else//H不可逆时,返回0 { cvReleaseMat(&H_IVT);//释放逆阵H_IVT QMessageBox::warning(this,tr("警告"),tr("变换矩阵H不可逆")); } } else ui->mosaicButton->setEnabled(true);//激活全景拼接按钮 } else //无法计算出变换矩阵,即两幅图中没有重合区域 { QMessageBox::warning(this,tr("警告"),tr("两图中无公共区域")); } ui->radioButton_horizontal->setEnabled(false);//禁用排列方向选择按钮 ui->radioButton_vertical->setEnabled(false); ui->matchButton->setEnabled(false);//禁用特征匹配按钮 }
int main( int argc, char** argv ) { //IplImage* img1, * img2, * stacked; struct feature* feat1, * feat2, * feat; struct feature** nbrs; struct kd_node* kd_root; //CvPoint pt1, pt2; double d0, d1; int n1, n2, k, i, m = 0; /* if( argc != 3 ) fatal_error( "usage: %s <img1> <img2>", argv[0] ); img1 = cvLoadImage( argv[1], 1 ); if( ! img1 ) fatal_error( "unable to load image from %s", argv[1] ); img2 = cvLoadImage( argv[2], 1 ); if( ! img2 ) fatal_error( "unable to load image from %s", argv[2] ); stacked = stack_imgs( img1, img2 ); */ char *query_img=argv[1]; char* match_img=argv[2]; fprintf( stderr, "Finding features in %s...\n", argv[1] ); //n1 = sift_features( img1, &feat1 ); n1=import_features(match_img, FEATURE_LOWE, &feat1); fprintf( stderr, "Finding features in %s...\n", argv[2] ); //n2 = sift_features( img2, &feat2 ); n2=import_features(query_img, FEATURE_LOWE, &feat2); kd_root = kdtree_build( feat2, n2 ); int cnt1=0, cnt2=0,cnt3=0; for( i = 0; i < n1; i++ ) { feat = feat1 + i; k = kdtree_bbf_knn( kd_root, feat, 2, &nbrs, KDTREE_BBF_MAX_NN_CHKS ); cnt1++; if( k == 2 ) { d0 = descr_dist_sq( feat, nbrs[0] ); d1 = descr_dist_sq( feat, nbrs[1] ); cnt2++; if( d0 < d1 * NN_SQ_DIST_RATIO_THR ) { //pt1 = cvPoint( cvRound( feat->x ), cvRound( feat->y ) ); //pt2 = cvPoint( cvRound( nbrs[0]->x ), cvRound( nbrs[0]->y ) ); //pt2.y += img1->height; //cvLine( stacked, pt1, pt2, CV_RGB(255,0,255), 1, 8, 0 ); m++; feat1[i].fwd_match = nbrs[0]; cnt3++; } } free( nbrs ); } fprintf( stderr, "cnt1: %d cnt2: %d cnt3:%d \n", cnt1, cnt2, cnt3 ); fprintf( stderr, "Found %d total matches\n", m ); //display_big_img( stacked, "Matches" ); //cvWaitKey( 0 ); /* UNCOMMENT BELOW TO SEE HOW RANSAC FUNCTION WORKS Note that this line above: feat1[i].fwd_match = nbrs[0]; is important for the RANSAC function to work. */ CvMat* H; //IplImage* xformed; int inliers=0; H = ransac_xform( feat1, n1, FEATURE_FWD_MATCH, lsq_homog, 4, 0.01, homog_xfer_err, 3.0, NULL, &inliers); cvReleaseMat( &H ); fprintf( stderr, "Found %d total inliers\n", inliers); /* if( H ) { xformed = cvCreateImage( cvGetSize( img2 ), IPL_DEPTH_8U, 3 ); cvWarpPerspective( img1, xformed, H, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, cvScalarAll( 0 ) ); cvNamedWindow( "Xformed", 1 ); cvShowImage( "Xformed", xformed ); cvWaitKey( 0 ); cvReleaseImage( &xformed ); cvReleaseMat( &H ); } */ //cvReleaseImage( &stacked ); //cvReleaseImage( &img1 ); //cvReleaseImage( &img2 ); kdtree_release( kd_root ); free( feat1 ); free( feat2 ); return 0; }
int main(int argc, char *argv[]) { IplImage* img1, * img2, * stacked1, *stacked2; char stemp[1024]; // printf("Reading images: %s and %s\n",argv[1],argv[2]); if(argc != 3) {printf("\n\nUsage: getsift [image1.jpg] [image2.jpg]\n\n"); exit(0);} img1=read_jpeg_file(argv[1]); img2=read_jpeg_file(argv[2]); stacked1 = stack_imgs( img1, img2 ); stacked2 = stack_imgs( img1, img2 ); struct feature* feat1, * feat2, * feat; struct feature** nbrs; struct feature** RANnb; struct kd_node* kd_root; CvPoint pt1, pt2; double d0, d1; int n1, n2, k, i,j, m = 0, n=0; printf("SIFT Features Extraction: %s\n", argv[1]); n1 = sift_features( img1, &feat1 ); printf("Numbers of Features from %s: %d\n",argv[1], n1); printf("SIFT Features Extraction: %s\n", argv[2]); n2 = sift_features( img2, &feat2 ); printf("Numbers of Features from %s: %d\n",argv[2], n2); sprintf(stemp,"%s.sift.jpg",argv[1]); draw_keypoint( img1, feat1, n1 ); write_jpeg_file(stemp,img1); sprintf(stemp,"%s.sift.jpg",argv[2]); draw_keypoint( img2, feat2, n2 ); write_jpeg_file(stemp,img2); FILE * feat1file; FILE * feat2file; feat1file=fopen("features1.txt","w+"); for(i=0;i<n1;i++) { fprintf(feat1file,"(%lf,%lf): {",(feat1+i)->x,(feat1+i)->y); for(j=0;j<FEATURE_MAX_D;j++) fprintf(feat1file,"% lf ",(feat1+i)->descr[j]); fprintf(feat1file,"}\n"); } printf("coordinate and descriptor of %s keypoints have been written in featfile1.txt\n",argv[1]); feat2file=fopen("features2.txt","w+"); for(i=0;i<n2;i++) { fprintf(feat2file,"(%lf,%lf): {",(feat2+i)->x,(feat2+i)->y); for(j=0;j<FEATURE_MAX_D;j++) fprintf(feat2file,"% lf ",(feat2+i)->descr[j]); fprintf(feat2file,"}\n"); } printf("coordinate and descriptor of %s keypoints have been written in featfile2.txt\n",argv[2]); kd_root = kdtree_build( feat2, n2 ); for( i = 0; i < n1; i++ ) { feat = feat1 + i; k = kdtree_bbf_knn( kd_root, feat, 2, &nbrs, KDTREE_BBF_MAX_NN_CHKS ); if( k == 2 ) { d0 = descr_dist_sq( feat, nbrs[0] ); d1 = descr_dist_sq( feat, nbrs[1] ); if( d0 < d1 * NN_SQ_DIST_RATIO_THR ) { pt1 = cvPoint( cvRound( feat->x ), cvRound( feat->y ) ); pt2 = cvPoint( cvRound( nbrs[0]->x ), cvRound( nbrs[0]->y ) ); pt2.y += img1->height; cvLine( stacked1, pt1, pt2, CV_RGB(255,0,255), 1, 8, 0 ); m++; feat1[i].fwd_match = nbrs[0]; } } free( nbrs ); } printf("Found %d total matches\n", m ); write_jpeg_file("matches.jpg",stacked1); CvMat* H; int number=0; H = ransac_xform( feat1, n1, FEATURE_FWD_MATCH, lsq_homog, 4, 0.25, homog_xfer_err, 27.0, &RANnb, &number ); for( i = 0; i < number; i++ ) { pt1 = cvPoint( cvRound( RANnb[i]->x ), cvRound( RANnb[i]->y ) ); pt2 = cvPoint( cvRound( RANnb[i]->fwd_match->x ), cvRound( RANnb[i]->fwd_match->y ) ); pt2.y += img1->height; cvLine( stacked2, pt1, pt2, CV_RGB(255,0,255), 1, 8, 0 ); n++; } printf("Found %d total matches after RANSAC\n", n ); write_jpeg_file("matches.ransac.jpg",stacked2); cvReleaseImage( &img1 ); cvReleaseImage( &img2 ); kdtree_release( kd_root ); free( feat1 ); free( feat2 ); return 0; }
void verify_get_all_matches(const double* refxys, int NR, const double* testxys, const double* testsigma2s, int NT, double effective_area, double distractors, double nsigma, double limit, il*** p_reflist, dl*** p_problist) { double* refcopy; kdtree_t* rtree; int Nleaf = 10; int i,j; double logd; double logbg; double loglimit; il** reflist; dl** problist; reflist = calloc(NT, sizeof(il*)); problist = calloc(NT, sizeof(dl*)); // Build a tree out of the index stars in pixel space... // kdtree scrambles the data array so make a copy first. refcopy = malloc(2 * NR * sizeof(double)); memcpy(refcopy, refxys, 2 * NR * sizeof(double)); rtree = kdtree_build(NULL, refcopy, NR, 2, Nleaf, KDTT_DOUBLE, KD_BUILD_SPLIT); logbg = log(1.0 / effective_area); logd = log(distractors / effective_area); loglimit = log(distractors / effective_area * limit); for (i=0; i<NT; i++) { const double* testxy; double sig2; kdtree_qres_t* res; testxy = testxys + 2*i; sig2 = testsigma2s[i]; logverb("\n"); logverb("test star %i: (%.1f,%.1f), sigma: %.1f\n", i, testxy[0], testxy[1], sqrt(sig2)); // find all ref stars within nsigma. res = kdtree_rangesearch_options(rtree, testxy, sig2*nsigma*nsigma, KD_OPTIONS_SORT_DISTS | KD_OPTIONS_SMALL_RADIUS); if (res->nres == 0) { kdtree_free_query(res); continue; } reflist[i] = il_new(4); problist[i] = dl_new(4); for (j=0; j<res->nres; j++) { double d2; int refi; double loggmax, logfg; d2 = res->sdists[j]; refi = res->inds[j]; // peak value of the Gaussian loggmax = log((1.0 - distractors) / (2.0 * M_PI * sig2 * NR)); // value of the Gaussian logfg = loggmax - d2 / (2.0 * sig2); if (logfg < loglimit) continue; logverb(" ref star %i, dist %.2f, sigmas: %.3f, logfg: %.1f (%.1f above distractor, %.1f above bg, %.1f above keep-limit)\n", refi, sqrt(d2), sqrt(d2 / sig2), logfg, logfg - logd, logfg - logbg, logfg - loglimit); il_append(reflist[i], refi); dl_append(problist[i], logfg); } kdtree_free_query(res); } kdtree_free(rtree); free(refcopy); *p_reflist = reflist; *p_problist = problist; }
int main( int argc, char** argv ) { int KDTREE_BBF_MAX_NN_CHKS = 200; float NN_SQ_DIST_RATIO_THR = 0.49; const CvScalar color = cvScalar( 255, 255, 0 ); ros::init(argc, argv, "SIFT"); ros::NodeHandle n; ros::Rate rate(33); ImageConverter ic; while ( !ic.ready ) { ros::spinOnce(); rate.sleep(); if ( !ros::ok() ) { printf("terminated by control_c\n"); return 0; } } string filepath = ros::package::getPath("sift") + "/"; ifstream fin( (filepath + "store.txt").data(), ios::in); //ifstream fin_main_pic( (filepath + "main_pic.txt").data(), ios::in); int pic_num = 5; string find; //cout << "how many pictures?" << endl; //cin >> pic_num; //cout << "which picture?" << endl; //cin >> find; time_t rawtime; struct tm * timeinfo; time ( &rawtime ); timeinfo = localtime ( &rawtime ); printf ( "The current date/time is: %s", asctime (timeinfo) ); char line[1024] = {0}; string* store = new string [pic_num+1]; string main_pic_name; int pic = 0; int find_pic = 0; while(fin.getline(line, sizeof(line))) { stringstream word(line); word >> store[pic]; store[pic] = filepath + store[pic]; /*if (store[pic] == find) { cout << store[pic] << endl; find_pic = pic; }*/ pic++; } //fin_main_pic.getline(line, sizeof(line)); //stringstream word(line); //word >> main_pic_name; //fin_main_pic.clear(); //fin_main_pic.close(); fin.clear(); fin.close(); IplImage* img; //IplImage* img1; struct feature* features;//, * features1; feature** features_all = new feature*[pic]; int* features_num = new int[pic]; for (int i = 0; i < pic; i++ ) features_num[i] = 0; IplImage** img_all = new IplImage*[pic]; for ( int i = 0; i < pic; i++ ) { //printf ( "Finding features in template picture %d\n", i ); img_all[i] = cvLoadImage( store[i].data(), 1 ); features_num[i] = sift_features( img_all[i], &features_all[i] ); printf ( "%d features in template picture %d\n", features_num[i], i ); time ( &rawtime ); timeinfo = localtime ( &rawtime ); printf ( "The current date/time is: %s", asctime (timeinfo) ); } /* printf ( "Finding features in main picture\n" ); img = cvLoadImage( main_pic_name.data(), 1 ); int n1 = sift_features( img, &features ); printf ( "%d features in main picture\n", n1 ); */ //cvShowImage( "main", img ); //for (int i = 0; i < n1; i++) //cvCircle( img, cvPoint(features[i].x, features[i].y), 5, color, 1, 8, 0 ); //cvShowImage( "Foundmain", img ); //cvShowImage( "template", img1 ); //for (int i = 0; i < n2; i++) //cvCircle( img1, cvPoint(features1[i].x, features1[i].y), 5, color, 1, 8, 0 ); //cvShowImage( "Foundtemplate", img1 ); bool features_catched = false; while ( ros::ok() ) { if ( ic.ready == true ) { ic.ready = false; *img = ic.curr_image; int n1 = sift_features( img, &features ); printf ( "%d features in main picture\n", n1 ); time ( &rawtime ); timeinfo = localtime ( &rawtime ); printf ( "The current date/time is: %s", asctime (timeinfo) ); features_catched = false; for ( int j = 0; j < pic ; j++ ) { IplImage* stacked; IplImage* ransac; struct feature* feat; struct feature** nbrs; struct kd_node* kd_root; CvPoint pt1, pt2; double d0, d1; int k, i, m = 0; CvMat point1_test; CvMat point2_test; double point1[3]; double point2[3] = { 0 }; stacked = stack_imgs( img, img_all[j] ); ransac = stack_imgs( img, img_all[j] ); kd_root = kdtree_build( features_all[j], features_num[j] ); for( i = 0; i < n1; i++ ) { feat = features + i; k = kdtree_bbf_knn( kd_root, feat, 2, &nbrs, KDTREE_BBF_MAX_NN_CHKS ); if( k == 2 ) { d0 = descr_dist_sq( feat, nbrs[0] ); d1 = descr_dist_sq( feat, nbrs[1] ); if( d0 < d1 * NN_SQ_DIST_RATIO_THR ) { //pt1 = cvPoint( cvRound( feat->x ), cvRound( feat->y ) ); //pt2 = cvPoint( cvRound( nbrs[0]->x ), cvRound( nbrs[0]->y ) ); //pt2.y += img->height; //cvCircle( stacked, pt1, 3, cvScalar( (i*10)%255, (i*10)%255, 127 ), 1, 8, 0 ); //cvCircle( stacked, pt2, 3, cvScalar( (i*10)%255, (i*10)%255, 127 ), 1, 8, 0 ); //cvLine( stacked, pt1, pt2, cvScalar( (i*10)%255, (i*10)%255, 127 ), 1, 8, 0 ); m++; features[i].fwd_match = nbrs[0]; } } free( nbrs ); } double accounts = m * 100 / (double)features_num[j]; printf( "%d total matches, accounts for %f %%, in pic %d\n", m, accounts, j); //cvNamedWindow( "Matches", 1 ); //cvShowImage( "Matches", stacked ); time ( &rawtime ); timeinfo = localtime ( &rawtime ); printf ( "The current date/time is: %s", asctime (timeinfo) ); CvMat* H = ransac_xform( features, n1, FEATURE_FWD_MATCH, lsq_homog, 4, 0.01, error, 2, NULL, NULL ); if( H ) { for( i = 0; i < n1; i++ ) { feat = features + i; k = kdtree_bbf_knn( kd_root, feat, 2, &nbrs, KDTREE_BBF_MAX_NN_CHKS ); if( k == 2 ) { d0 = descr_dist_sq( feat, nbrs[0] ); d1 = descr_dist_sq( feat, nbrs[1] ); if( d0 < d1 * NN_SQ_DIST_RATIO_THR ) { pt1 = cvPoint( cvRound( feat->x ), cvRound( feat->y ) ); pt2 = cvPoint( cvRound( nbrs[0]->x ), cvRound( nbrs[0]->y ) ); pt2.y += img->height; point1[0] = pt1.x; point1[1] = pt1.y; point1[2] = 1.0; cvInitMatHeader( &point1_test, 3, 1, CV_64FC1, point1, CV_AUTOSTEP ); cvInitMatHeader( &point2_test, 3, 1, CV_64FC1, point2, CV_AUTOSTEP ); cvMatMul( H, &point1_test, &point2_test ); /*if ( abs( point2[0]/point2[2]-pt2.x) < 2 && abs( point2[1]/point2[2]+img->height-pt2.y) < 2 ) { cvCircle( ransac, pt1, 3, cvScalar( (i*10)%255, (i*10)%255, 127 ), 1, 8, 0 ); cvCircle( ransac, pt2, 3, cvScalar( (i*10)%255, (i*10)%255, 127 ), 1, 8, 0 ); cvLine( ransac, pt1, pt2, cvScalar( (i*10)%255, (i*10)%255, 127 ), 1, 8, 0 ); }*/ // features[i].fwd_match = nbrs[0]; } } free( nbrs ); //printf("features catched, going to exit\n"); } //cvNamedWindow( "Xformed" ); //cvShowImage( "Xformed", ransac ); features_catched = true; time ( &rawtime ); timeinfo = localtime ( &rawtime ); printf ( "ransac.. The current date/time is: %s", asctime (timeinfo) ); } //cvWaitKey( 0 ); cvReleaseImage( &ransac ); cvReleaseMat( &H ); //cvDestroyWindow( "main" ); //cvDestroyWindow( "Foundmain" ); //cvDestroyWindow( "template" ); //cvDestroyWindow( "Foundtemplate" ); //cvReleaseImage( &img_all[j] ); cvReleaseImage( &stacked ); kdtree_release( kd_root ); } if (!features_catched) { printf("Sorry, there is no item in the picture\n"); } else { printf("Item catched in the picture!\n"); } } ros::spinOnce(); rate.sleep(); } //cvReleaseImage( &img ); free( features ); for ( int i = 0; i < pic; i++ ) { free( features_all[i] ); } free(features_all); return 0; }
int main( int argc, char** argv ) { IplImage* img1, * img2, * stacked; struct feature* feat1, * feat2, * feat; struct feature** nbrs; struct kd_node* kd_root; CvPoint pt1, pt2; double d0, d1; int n1, n2, k, i, m = 0; img1 = cvLoadImage( img1_file, 1 ); if( ! img1 ) fatal_error( "unable to load image from %s", img1_file ); img2 = cvLoadImage( img2_file, 1 ); if( ! img2 ) fatal_error( "unable to load image from %s", img2_file ); stacked = stack_imgs( img1, img2 ); fprintf( stderr, "Finding features in %s...\n", img1_file ); n1 = sift_features( img1, &feat1 ); fprintf( stderr, "Finding features in %s...\n", img2_file ); n2 = sift_features( img2, &feat2 ); kd_root = kdtree_build( feat2, n2 );//½¨Á¢feat2µÄkd tree for( i = 0; i < n1; i++ ) { feat = feat1 + i; k = kdtree_bbf_knn( kd_root, feat, 2, &nbrs, KDTREE_BBF_MAX_NN_CHKS ); if( k == 2 ) { d0 = descr_dist_sq( feat, nbrs[0] ); d1 = descr_dist_sq( feat, nbrs[1] ); if( d0 < d1 * NN_SQ_DIST_RATIO_THR ) { pt1 = cvPoint( cvRound( feat->x ), cvRound( feat->y ) );//feat1 pt2 = cvPoint( cvRound( nbrs[0]->x ), cvRound( nbrs[0]->y ) );//feat2 pt2.y += img1->height; cvLine( stacked, pt1, pt2, CV_RGB(255,0,255), 1, 8, 0 ); m++; feat1[i].fwd_match = nbrs[0]; } } free( nbrs ); } fprintf( stderr, "Found %d total matches\n", m ); cvNamedWindow( "Matches", 1 ); cvShowImage( "Matches", stacked ); cvWaitKey( 0 ); draw_features_o( img1,feat1,n1); draw_features_o( img2,feat2,n2); cvSaveImage(img1_sfile,img1); cvSaveImage(img2_sfile,img2); cvShowImage("img1",img1); cvShowImage("img2",img2); cvWaitKey(0); /* UNCOMMENT BELOW TO SEE HOW RANSAC FUNCTION WORKS Note that this line above: feat1[i].fwd_match = nbrs[0]; is important for the RANSAC function to work. */ /* { CvMat* H; H = ransac_xform( feat1, n1, FEATURE_FWD_MATCH, lsq_homog, 4, 0.01, homog_xfer_err, 3.0, NULL, NULL ); if( H ) { IplImage* xformed; xformed = cvCreateImage( cvGetSize( img2 ), IPL_DEPTH_8U, 3 ); cvWarpPerspective( img1, xformed, H, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, cvScalarAll( 0 ) ); cvNamedWindow( "Xformed", 1 ); cvShowImage( "Xformed", xformed ); cvWaitKey( 0 ); cvReleaseImage( &xformed ); cvReleaseMat( &H ); } } */ cvReleaseImage( &stacked ); cvReleaseImage( &img1 ); cvReleaseImage( &img2 ); kdtree_release( kd_root ); free( feat1 ); free( feat2 ); return 0; }
// Match Thread void* matchThread(void* matchData) { // normal match local variables struct feature* feat= NULL; struct feature** nbrs = NULL; struct kd_node* kd_root = NULL; double d0, d1; int k, i, x, y, m = 0; // arguments passed to thread char file[25]; char file2[25]; struct mData* temp; temp = (struct mData*) matchData; IplImage* img1 = temp->img1; IplImage* img2 = temp->img2; int index1 = temp->index1; int index2 = temp->index2; CvMat* homography = temp->homography; sprintf(file, "features/temp%d", index1); sprintf(file2, "features/temp%d", index2); struct feature* feat1; struct feature* feat2; int numFeatures1 = import_features(file, FEATURE_LOWE, &feat1); int numFeatures2 = import_features(file2, FEATURE_LOWE, &feat2); // printf("running the matching function\n"); // matching function kd_root = kdtree_build( feat2, numFeatures2 ); for( i = 0; i < numFeatures1; i++ ) { feat = feat1 + i; k = kdtree_bbf_knn( kd_root, feat, 2, &nbrs, KDTREE_BBF_MAX_NN_CHKS ); if( k == 2 ) { d0 = descr_dist_sq( feat, nbrs[0] ); d1 = descr_dist_sq( feat, nbrs[1] ); if( d0 < d1 * NN_SQ_DIST_RATIO_THR ) { m++; feat1[i].fwd_match = nbrs[0]; } } free( nbrs ); } if (DEBUG) printf("computing transform\n"); // Compute homography CvMat* H; H = ransac_xform(feat1, numFeatures1, FEATURE_FWD_MATCH, lsq_homog, 4, 0.01, homog_xfer_err, 3.0, NULL, NULL); if (DEBUG) printf("past ransac_xform\n"); if (!H) { if (DEBUG) printf("setting empty homography...\n"); H = cvCreateMat(3, 3, CV_64F); for (x = 0; x < 3; x++) { for (y = 0; y < 3; y++) { cvmSet(H, x, y, 1000000.0); } } } kdtree_release(kd_root); if (DEBUG) printf("setting homography\n"); for (x = 0; x < 3; x++) { for (y = 0; y < 3; y++) { double tempValue = cvmGet(H, x, y); cvmSet(homography, x, y, tempValue); } } if (DEBUG) printf("past setting homography\n"); free(feat1); free(feat2); pthread_exit(NULL); }
int CUtil_Sift::CmpSiftFilesF_New( const char* siftfile1,const char* siftfile2 ) { if ( !siftfile1 || !siftfile2 ) { return -1; } struct feature* feat1, * feat2, * feat; int n1, n2, k, i, m=0; /////////////////////////////////////////////////////////////// struct feature** nbrs; struct kd_node* kd_root; double d0, d1; ///////////////////////////////////////////////////////////////////// int upimgwid,upimghigh; int downimgwid,downimghigh; int upwid,uphigh; int downwid,downhigh; double tempx,tempy; int tempnwid,tempnhigh; int j; #define nwid 5 #define nhigh 8 int numdown[nwid*nhigh] = {0}; int numup[nwid*nhigh] = {0}; struct feature *upfeat[nwid*nhigh]; struct feature *downfeat[nwid*nhigh]; n1 = import_features((char*)siftfile1,FEATURE_LOWE,&feat1); if(n1<1) { return -1; } n2 = import_features((char*)siftfile2,FEATURE_LOWE,&feat2); if ( n2<1 ) { return -1; } ///////////////////////////////////////////////////////////////// // upimgwid = img1->width; // upimghigh = img1->height; upwid = upimgwid/nwid; uphigh = upimghigh/nhigh; ///////////////////////////////////////////////////////////////// // downimgwid = img2->width; // downimghigh = img2->height; downwid = downimgwid/nwid; downhigh = downimghigh/nhigh; /////////////////////////////////////////////////////////////// //将feature2按行列分块 for(i=0; i<nwid*nhigh; i++) { upfeat[i] = NULL; upfeat[i] = (struct feature *)malloc(300*sizeof(struct feature)); downfeat[i] = NULL; downfeat[i] = (struct feature *)malloc(300*sizeof(struct feature)); } for(i=0; i<n2; i++) { tempx = (*feat2).x; tempy = (*feat2).y; tempnwid = (int)(tempx/downwid); if(tempnwid == nwid) tempnwid = nwid -1; tempnhigh = (int)(tempy/downhigh); if(tempnhigh == nhigh) tempnhigh = nhigh-1; // *(*(downfeat+tempnhigh*nwid+tempnwid)) = feat2; *(downfeat[tempnhigh*nwid+tempnwid]+*(numdown+tempnhigh*nwid+tempnwid)) = *feat2; (*(numdown+tempnhigh*nwid+tempnwid))++; // (downfeat[tempnhigh*nwid+tempnwid]) ++; feat2 ++; } ///////////////////////////////////////////////////////////////// //将feature1按行列分块 for(i=0; i<n1; i++) { tempx = (*feat1).x; tempy = (*feat1).y; tempnwid = (int)(tempx/upwid); if(tempnwid == nwid) tempnwid = nwid -1; tempnhigh = (int)(tempy/uphigh); if(tempnhigh == nhigh) tempnhigh = nhigh-1; *(upfeat[tempnhigh*nwid+tempnwid]+*(numup+tempnhigh*nwid+tempnwid)) = *feat1; (*(numup+tempnhigh*nwid+tempnwid))++; // (*(upfeat+tempnhigh*nwid+tempnwid))++; feat1 ++; } //按块寻找匹配点 for(i=0; i<nwid*nhigh; i++) { if(numdown[i] == 0) continue; kd_root = kdtree_build( downfeat[i], numdown[i]); for(j=0; j<*(numup+i); j++) { if(numup[i] == 0) continue; feat = upfeat[i]+j; k = kdtree_bbf_knn( kd_root, feat, 2, &nbrs, KDTREE_BBF_MAX_NN_CHKS ); if( k == 2 ) { d0 = descr_dist_sq( feat, nbrs[0] ); d1 = descr_dist_sq( feat, nbrs[1] ); if( d0 < d1 * NN_SQ_DIST_RATIO_THR ) { m++; feat->fwd_match = nbrs[0]; } } free(nbrs); } kdtree_release( kd_root ); free(upfeat[i]); upfeat[i] = NULL; free(downfeat[i]); downfeat[i] = NULL; } return m; }
int main( int argc, char** argv ) { IplImage* img1, * img2, * stacked; struct feature* feat1, * feat2, * feat; struct feature** nbrs; struct kd_node* kd_root; CvPoint pt1, pt2; double d0, d1; int n1, n2, k, i, m = 0; int match_cnt = 0; //CvMat *im1_mask = cvCreateMat( img1->height, img1->width, CV_64FC1 ); //CvMat *im2_mask = cvCreateMat( img2->height, img2->width, CV_64FC1 ); //cvSet( im1_mask, cvScalar( 1, 0, 0, 0 ), NULL ); //cvSet( im2_mask, cvScalar( 1, 0, 0, 0 ), NULL ); if( argc != 3 ) fatal_error( "usage: %s <img1> <img2>", argv[0] ); img1 = cvLoadImage( argv[1], 1 ); if( ! img1 ) fatal_error( "unable to load image from %s", argv[1] ); img2 = cvLoadImage( argv[2], 1 ); if( ! img2 ) fatal_error( "unable to load image from %s", argv[2] ); stacked = stack_imgs( img1, img2 ); fprintf( stderr, "Finding features in %s...\n", argv[1] ); n1 = sift_features( img1, &feat1 ); fprintf( stderr, "Finding features in %s...\n", argv[2] ); n2 = sift_features( img2, &feat2 ); kd_root = kdtree_build( feat2, n2 ); for( i = 0; i < n1; i++ ) { feat = feat1 + i; k = kdtree_bbf_knn( kd_root, feat, 2, &nbrs, KDTREE_BBF_MAX_NN_CHKS ); if( k == 2 ) { d0 = descr_dist_sq( feat, nbrs[0] ); d1 = descr_dist_sq( feat, nbrs[1] ); if( d0 < d1 * NN_SQ_DIST_RATIO_THR ) { if( m >= 2000 ) break; pt1 = cvPoint( cvRound( feat->x ), cvRound( feat->y ) ); pt2 = cvPoint( cvRound( nbrs[0]->x ), cvRound( nbrs[0]->y ) ); pt2.y += img1->height; cvLine( stacked, pt1, pt2, CV_RGB(255,0,255), 1, 8, 0 ); m++; feat1[i].fwd_match = nbrs[0]; } } free( nbrs ); } fprintf( stderr, "Found %d total matches\n", m ); display_big_img( stacked, "Matches" ); cvWaitKey( 0 ); /*********************************************************************************************************/ CvMat* H; IplImage* xformed; H = ransac_xform( feat1, n1, FEATURE_FWD_MATCH, lsq_homog, 4, 0.01, homog_xfer_err, 3.0, NULL, NULL ); /* output H */ printf("xform Homography Matrix is :\n"); printMat( H ); /* get the size of new image */ double XDATA[2]; double YDATA[2]; CvSize new_size; CvSize im1_size = cvGetSize( img1 ); CvSize im2_size = cvGetSize( img2 ); new_size = get_Stitched_Size( im1_size, im2_size, H, XDATA, YDATA ); /*declare the mask*/ CvMat *im1_mask = cvCreateMat( new_size.height, new_size.width, CV_64FC1 ); CvMat *im2_mask = cvCreateMat( new_size.height, new_size.width, CV_64FC1 ); CvMat *im1_tempMask = cvCreateMat( im1_size.height, im1_size.width, CV_64FC1 ); CvMat *im2_tempMask = cvCreateMat( im2_size.height, im2_size.width, CV_64FC1 ); cvSet( im1_tempMask, cvScalar(1,0,0,0), NULL ); cvSet( im2_tempMask, cvScalar(1,0,0,0), NULL ); /* get translation Matrix for Aligning */ CvMat *T = cvCreateMat( 3, 3, CV_64FC1 ); double tx = 0; double ty = 0; if( XDATA[0] < 0 ) { tx = -XDATA[0] ; printf("tx = %f\n", tx ); } if( YDATA[0] < 0 ) { ty = -YDATA[0]; printf("ty = %f\n", ty ); } cvmSet( T, 0, 0, 1 ); cvmSet( T, 0, 2, tx ); cvmSet( T, 1, 1, 1 ); cvmSet( T, 1, 2, ty ); cvmSet( T, 2, 2, 1 ); printf("T Matrix:\n"); printMat( T ); /* Transform and Align image2 */ cvGEMM( T, H, 1, NULL, 0, H, 0 ); printMat( H ); xformed = cvCreateImage( new_size, IPL_DEPTH_8U, 3 ); cvWarpPerspective( img1, xformed, H, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, cvScalarAll( 0 ) ); cvNamedWindow( "Xformed1", 1 ); cvShowImage( "Xformed1", xformed ); cvWaitKey( 0 ); cvDestroyWindow("Xformed1"); //cvSaveImage("im2.png", xformed); cvWarpPerspective( im1_tempMask, im1_mask, H, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, cvScalarAll( 0 ) ); //cvSaveImage("im1_mask.png", im1_mask); cvNamedWindow( "im1_mask", 1 ); cvShowImage( "im1_mask", im1_mask ); cvWaitKey( 0 ); cvDestroyWindow("im1_mask"); /* Align image1 to bound */ cvWarpPerspective( im2_tempMask, im2_mask, T, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, cvScalarAll( 0 ) ); //cvSaveImage( "im2_mask.png", im2_mask ); cvNamedWindow( "im12_mask", 1 ); cvShowImage( "im2_mask", im2_mask ); cvWaitKey( 0 ); cvDestroyWindow("im2_mask"); cvSetImageROI( xformed, cvRect( tx, ty, img2->width, img2->height ) ); cvCopy( img2, xformed, NULL ); IplImage* huaijin = cvCreateImage( new_size, IPL_DEPTH_8U, 3 ); cvWarpPerspective( img2, huaijin, T, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, cvScalarAll( 0 ) ); cvNamedWindow( "im12_mask_i", 1 ); cvShowImage( "im2_mask_i", huaijin); cvWaitKey( 0 ); cvDestroyWindow("im2_mask_i"); cvResetImageROI( xformed ); //cvSaveImage( "re.png", xformed ); /* composite */ cvNamedWindow( "Xformed", 1 ); cvShowImage( "Xformed", xformed ); cvWaitKey( 0 ); cvDestroyWindow("Xformed"); /* */ cvReleaseImage( &xformed ); cvReleaseMat( &H ); cvReleaseMat( &im1_tempMask ); cvReleaseMat( &im2_tempMask ); cvReleaseMat( &T ); cvReleaseMat ( &im1_mask ); cvReleaseMat ( &im2_mask ); cvReleaseImage( &stacked ); cvReleaseImage( &img1 ); cvReleaseImage( &img2 ); kdtree_release( kd_root ); free( feat1 ); free( feat2 ); /**************************************************** * using RANSAC algorithm get the Homegraphy Matrix * get T image1-->image2 * * n_pts the number of points for estimating parameters * * * * create unique indics of matchs : get_randi( int j ) * * * ******slove*********** * 1.create the coff matrix * 2.Ah=0 -->decomposit A = UDV^T using gsl * 3 * [ v19 v29 v39 ... v99 ] * h = ------------------------- * v99 * * ***************************************************/ /* CvMat *H1 = cvCreateMat( 3, 3, CV_64FC1 ); CvMat *inliers_mask = cvCreateMat( m, 1, CV_64FC1 ); RANSAC_Homography( m, pts1, pts2, H1, inliers_mask ); printf("my code Homography Matrix is :\n"); for ( i = 0; i < H->rows; i++ ){ for( k = 0; k < H->cols; k++ ){ printf("%f ",cvmGet( H1, i, k )); } printf("\n"); } cvReleaseMat( &H1 ); cvReleaseMat( &inliers_mask );*/ /*********************************************** * composit image1 & image2 * 1) transform image2 to image * * 2)***stitched image bounds**** * W = max( [size(im1,2) size(im1,2)-XDATA(1) size(im2,2) size(im2,2)+XDATA(1)] ); * H = max( [size(im1,1) size(im1,1)-YDATA(1) size(im2,1) size(im2,1)+YDATA(1)] ); * * 3)*** Align image1 to bound *** * * 4)*** Align image2 to bound *** * * 5)*** Check size of bounds *** * * 6)*** combine both images *** * im1_mask * im2_mask * im1_part_mask * im2_part_mask * com_part_mask * stitched_image * * 7)****copy im2 transformed to ROI of stitching plan ( just a idear ) * ************************************************/ void compositImages( IplImage *im1, IplImage *im2, CvMat *H ) { /* 1.create a plan */ /* 2.transform im2 & im2_mask */ /* 3.emstime translation of im2 --T cp im1 -->plan with cvRect( tx, ty) */ /* 4.cp tranformed im2 to plan with im2_mask where im2_mask has the same size with plan */ } return 0; }
int main( int argc, char** argv ) { struct feature* feat1, * feat2, * feat; struct feature** nbrs; struct kd_node* kd_root; double d0, d1; int n1, n2, k, i, m = 0; if( argc != 3 ) fatal_error( "usage: %s <keydescr1> <keydescr2>", argv[0] ); n1 = import_features( argv[1], feat_type, &feat1 ); n2 = import_features( argv[2], feat_type, &feat2 ); if( n1 < 0 ) fatal_error( "unable to load key descriptors from %s", argv[1] ); if( n2 < 0 ) fatal_error( "unable to load key descriptors from %s", argv[2] ); printf("%d features presenti nel modello.\n", n1); printf("%d features presenti nell'immagine.\n", n2); kd_root = kdtree_build( feat2, n2 ); for( i = 0; i < n1; i++ ) { feat = feat1 + i; k = kdtree_bbf_knn( kd_root, feat, 2, &nbrs, KDTREE_BBF_MAX_NN_CHKS ); if( k == 2 ) { // Controlla d0 = descr_dist_sq( feat, nbrs[0] ); d1 = descr_dist_sq( feat, nbrs[1] ); if( d0 < d1 * NN_SQ_DIST_RATIO_THR ) { m++; feat1[i].fwd_match = nbrs[0]; } } free( nbrs ); } #ifdef RANSAC { CvMat* H; IplImage* xformed; struct feature ** inliers; int n_inliers; H = ransac_xform( feat1, n1, FEATURE_FWD_MATCH, lsq_homog, 4, 0.01, homog_xfer_err, 8.0, &inliers, &n_inliers ); if( H ) { if ( cvmGet( H, 1, 2 ) < 120.0 && cvmGet( H, 0, 2 ) < 120.0 && ( fabs(cvmGet( H, 0, 0)) >= 0.000001 || fabs(cvmGet( H, 0, 1)) >= 0.000001 || fabs(cvmGet( H, 1, 0)) >= 0.000001 || fabs(cvmGet( H, 1, 1)) >= 0.000001 || fabs(cvmGet( H, 2, 0)) >= 0.000001 || fabs(cvmGet( H, 2, 1)) >= 0.000001 ) ) { // TROVATO printf("RANSAC OK\n"); /* xformed = cvCreateImage( cvGetSize( img2 ), IPL_DEPTH_8U, 3 ); cvWarpPerspective( img1, xformed, H, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, cvScalarAll( 0 ) ); cvNamedWindow( "Xformed", 1 ); cvShowImage( "Xformed", xformed ); cvWaitKey( 0 ); cvReleaseImage( &xformed ); */ printf("N. inliers: %d\n", n_inliers); } else { // Trovato ma probabilmente la matrice di trasformazione e' sbagliata. printf("RANSAC FAIL\n"); } cvReleaseMat( &H ); } else { printf("RANSAC FAIL\n"); } } #endif fprintf( stderr, "Found %d total matches\n", m ); kdtree_release( kd_root ); free( feat1 ); free( feat2 ); return 0; }
int main(int argc, char** args) { int argchar; kdtree_t* kd; int Nleaf = 25; char* infn = NULL; char* outfn = NULL; char* tychofn = NULL; char* crossfn = NULL; char* progname = args[0]; FILE* f; tycstar_t* tycstars = NULL; int Ntyc = 0; int exttype = KDT_EXT_DOUBLE; int datatype = KDT_DATA_U32; int treetype = KDT_TREE_U32; int tt; int buildopts = 0; int i, N, D; dl* ras; dl* decs; dl* hds; fl* mag1s; fl* mag2s; fl* mag3s; int nbad = 0; int nox = 0; int* hd; double* xyz; qfits_header* hdr; while ((argchar = getopt (argc, args, OPTIONS)) != -1) switch (argchar) { case 'T': tychofn = optarg; break; case 'X': crossfn = optarg; break; case 'R': Nleaf = (int)strtoul(optarg, NULL, 0); break; case 't': treetype = kdtree_kdtype_parse_tree_string(optarg); break; case 'd': datatype = kdtree_kdtype_parse_data_string(optarg); break; case 'b': buildopts |= KD_BUILD_BBOX; break; case 's': buildopts |= KD_BUILD_SPLIT; break; case 'S': buildopts |= KD_BUILD_SPLITDIM; break; case '?': fprintf(stderr, "Unknown option `-%c'.\n", optopt); case 'h': printHelp(progname); return 0; default: return -1; } if (optind != argc - 2) { printHelp(progname); exit(-1); } infn = args[optind]; outfn = args[optind+1]; if (!(buildopts & (KD_BUILD_BBOX | KD_BUILD_SPLIT))) { printf("You need bounding-boxes or splitting planes!\n"); printHelp(progname); exit(-1); } if (tychofn || crossfn) { if (!(tychofn && crossfn)) { printf("You need both -T <Tycho2> and -X <Crossref> to do cross-referencing.\n"); exit(-1); } } if (tychofn) { int i, N; tycho2_fits* tyc; FILE* f; int nx, nox; int lastgrass = 0; tyc = tycho2_fits_open(tychofn); if (!tyc) { ERROR("Failed to open Tycho-2 catalog."); exit(-1); } printf("Reading Tycho-2 catalog...\n"); N = tycho2_fits_count_entries(tyc); tycstars = calloc(N, sizeof(tycstar_t)); for (i=0; i<N; i++) { tycho2_entry* te; int grass = (i*80 / N); if (grass != lastgrass) { printf("."); fflush(stdout); lastgrass = grass; } te = tycho2_fits_read_entry(tyc); tycstars[i].tyc1 = te->tyc1; tycstars[i].tyc2 = te->tyc2; tycstars[i].tyc3 = te->tyc3; tycstars[i].ra = te->ra; tycstars[i].dec = te->dec; tycstars[i].mag_BT = te->mag_BT; tycstars[i].mag_VT = te->mag_VT; tycstars[i].mag_HP = te->mag_HP; } tycho2_fits_close(tyc); printf("Sorting...\n"); qsort(tycstars, N, sizeof(tycstar_t), compare_tycs); Ntyc = N; f = fopen(crossfn, "rb"); if (!f) { SYSERROR("Failed to open cross-reference file %s", crossfn); exit(-1); } nx = 0; nox = 0; while (TRUE) { char buf[1024]; int tyc1, tyc2, tyc3, hd, nhd, ntyc; char ftyc, sptype0, sptype1, sptype2; tycstar_t* s; if (!fgets(buf, sizeof(buf), f)) { if (ferror(f)) { SYSERROR("Failed to read a line of text from the cross-reference file"); exit(-1); } break; } if (sscanf(buf, " %d %d %d%c %d %c%c%c %d %d", &tyc1, &tyc2, &tyc3, &ftyc, &hd, &sptype0, &sptype1, &sptype2, &nhd, &ntyc) != 10) { ERROR("Failed to parse line: \"%s\"", buf); } //printf("%i %i %i %i %i %i\n", tyc1, tyc2, tyc3, hd, nhd, ntyc); s = find_tycho(tycstars, Ntyc, tyc1, tyc2, tyc3); if (!s) { ERROR("Failed to find Tycho-2 star %i-%i-%i", tyc1, tyc2, tyc3); nox++; } else { s->hd = hd; s->ntyc = ntyc; } nx++; } fclose(f); printf("Read %i cross-references.\n", nx); printf("Failed to find %i cross-referenced Tycho-2 stars.\n", nox); printf("Sorting...\n"); qsort(tycstars, N, sizeof(tycstar_t), compare_hds); } f = fopen(infn, "rb"); if (!f) { SYSERROR("Failed to open input file %s", infn); exit(-1); } ras = dl_new(1024); decs = dl_new(1024); hds = il_new(1024); mag1s = fl_new(1024); mag2s = fl_new(1024); mag3s = fl_new(1024); printf("Reading HD catalog...\n"); for (;;) { char buf[1024]; double ra, dec; int hd; float mag1, mag2, mag3; mag1 = mag2 = mag3 = 0.0; if (!fgets(buf, sizeof(buf), f)) { if (ferror(f)) { SYSERROR("Failed to read a line of text from the input file"); exit(-1); } break; } if (buf[0] == '#') continue; if (buf[0] == '\n') continue; if (sscanf(buf, " %lf| %lf| %d", &ra, &dec, &hd) < 3) { // ignore three invalid lines if (nbad > 3) { ERROR("Failed to parse line: \"%s\"", buf); } nbad++; } else { if (tycstars) { tycstar_t* s = find_hd(tycstars, Ntyc, hd); if (!s) { //printf("Failed to find cross-ref for HD %i\n", hd); nox++; } else { ra = s->ra; dec = s->dec; mag1 = s->mag_VT; mag2 = s->mag_BT; mag3 = s->mag_HP; } } dl_append(ras, ra); dl_append(decs, dec); il_append(hds, hd); fl_append(mag1s, mag1); fl_append(mag2s, mag2); fl_append(mag3s, mag3); } } fclose(f); N = dl_size(ras); printf("Read %i entries and %i bad lines.\n", N, nbad); if (dl_size(ras) != HD_NENTRIES) { printf("WARNING: expected %i Henry Draper catalog entries.\n", HD_NENTRIES); } if (nox) { printf("Found %i HD entries with no cross-reference (expect this to be about 1%%)\n", nox); } hd = malloc(sizeof(int) * N); il_copy(hds, 0, N, hd); il_free(hds); for (i=0; i<N; i++) if (hd[i] != i+1) { printf("Line %i is HD %i\n", i+1, hd[i]); break; } // HACK - don't allocate 'em in the first place... free(hd); xyz = malloc(sizeof(double) * 3 * N); for (i=0; i<N; i++) { radecdeg2xyzarr(dl_get(ras, i), dl_get(decs, i), xyz + 3*i); } dl_free(ras); dl_free(decs); tt = kdtree_kdtypes_to_treetype(exttype, treetype, datatype); D = 3; { // limits of the kdtree... double lo[] = {-1.0, -1.0, -1.0}; double hi[] = { 1.0, 1.0, 1.0}; kd = kdtree_new(N, D, Nleaf); kdtree_set_limits(kd, lo, hi); } printf("Building tree...\n"); kd = kdtree_build(kd, xyz, N, D, Nleaf, tt, buildopts); hdr = qfits_header_default(); qfits_header_add(hdr, "AN_FILE", "HDTREE", "Henry Draper catalog kdtree", NULL); BOILERPLATE_ADD_FITS_HEADERS(hdr); fits_add_long_history(hdr, "This file was created by the following command-line:"); fits_add_args(hdr, args, argc); if (kdtree_fits_write(kd, outfn, hdr)) { ERROR("Failed to write kdtree"); exit(-1); } // Write mags as tag-along table. { fitstable_t* tag; tag = fitstable_open_for_appending(outfn); if (!tag) { ERROR("Failed to open kd-tree file for appending"); exit(-1); } fitstable_add_write_column(tag, fitscolumn_float_type(), "MAG_VT", ""); fitstable_add_write_column(tag, fitscolumn_float_type(), "MAG_BT", ""); fitstable_add_write_column(tag, fitscolumn_float_type(), "MAG_HP", ""); if (fitstable_write_header(tag)) { ERROR("Failed to write tag-along header"); exit(-1); } for (i=0; i<N; i++) { fitstable_write_row(tag, fl_get(mag1s, i), fl_get(mag2s, i), fl_get(mag3s, i)); } if (fitstable_fix_header(tag)) { ERROR("Failed to fix tag-along header"); exit(-1); } if (fitstable_close(tag)) { ERROR("Failed to close tag-along data"); exit(-1); } } fl_free(mag1s); fl_free(mag2s); fl_free(mag3s); printf("Done.\n"); qfits_header_destroy(hdr); free(xyz); kdtree_free(kd); free(tycstars); return 0; }
int match( const char * img1fname, const char * img2fname, CvMat **H ) { double scale = 10.0; IplImage* img1, * img2, * img1orig, * img2orig; struct feature* feat1, * feat2, * feat; struct feature** nbrs; struct kd_node* kd_root; CvPoint pt1, pt2; double d0, d1; int n1, n2, k, i, m = 0; img1orig = cvLoadImage( img1fname, CV_LOAD_IMAGE_COLOR ); if( ! img1orig ) fatal_error( "unable to load image from %s", img1fname ); img1 = cvCreateImage( cvSize( (int)(img1orig->width/scale), (int)(img1orig->height/scale) ), img1orig->depth, img1orig->nChannels ); cvResize( img1orig, img1, CV_INTER_AREA ); cvReleaseImage( &img1orig ); img2orig = cvLoadImage( img2fname, CV_LOAD_IMAGE_COLOR ); if( ! img2orig ) fatal_error( "unable to load image from %s", img2fname ); img2 = cvCreateImage( cvSize( (int)(img2orig->width/scale), (int)(img2orig->height/scale) ), img2orig->depth, img2orig->nChannels ); cvResize( img2orig, img2, CV_INTER_AREA ); cvReleaseImage( &img2orig ); fprintf( stdout, "Finding features in %s...\n", img1fname ); n1 = sift_features( img1, &feat1 ); fprintf( stdout, "Finding features in %s...\n", img2fname ); n2 = sift_features( img2, &feat2 ); cvReleaseImage( &img1 ); cvReleaseImage( &img2 ); kd_root = kdtree_build( feat2, n2 ); for( i = 0; i < n1; i++ ) { feat = feat1 + i; k = kdtree_bbf_knn( kd_root, feat, 2, &nbrs, KDTREE_BBF_MAX_NN_CHKS ); if( k == 2 ) { d0 = descr_dist_sq( feat, nbrs[0] ); d1 = descr_dist_sq( feat, nbrs[1] ); if( d0 < d1 * NN_SQ_DIST_RATIO_THR ) { /* pt1 = cvPoint( cvRound( feat->x ), cvRound( feat->y ) ); pt2 = cvPoint( cvRound( nbrs[0]->x ), cvRound( nbrs[0]->y ) ); pt2.y += img1->height; */ m++; feat1[i].fwd_match = nbrs[0]; } } free( nbrs ); } // scale feature coordinates back in to original image size for( i = 0; i < n2; i++ ) { feat2[i].img_pt.x *= scale; feat2[i].img_pt.y *= scale; } for( i = 0; i < n1; i++ ) { feat1[i].img_pt.x *= scale; feat1[i].img_pt.y *= scale; } fprintf( stdout, "Found %d total matches\n", m ); { // CvMat* H; *H = ransac_xform( feat1, n1, FEATURE_FWD_MATCH, lsq_homog, 4, 0.01, homog_xfer_err, 3.0, NULL, NULL ); if(*H != NULL) { printf("Perspective transform:\n"); for( i = 0; i < 3; i++ ) { printf("%0.6f %0.6f %0.6f\n", (*H)->data.db[3*i+0], (*H)->data.db[3*i+1], (*H)->data.db[3*i+2]); } } else { printf("Unable to compute transform\n"); } /* CvMat * Hinv = cvCreateMat(3,3,CV_64FC1); cvInvert( *H, Hinv, CV_LU ); printf("Inverse transform:\n"); for( i = 0; i < 3; i++ ) { printf("%0.6f %0.6f %0.6f\n", Hinv->data.db[3*i+0], Hinv->data.db[3*i+1], Hinv->data.db[3*i+2]); } cvReleaseMat( &Hinv ); */ /* if( H ) { IplImage* xformed; img2orig = cvLoadImage( img2fname, CV_LOAD_IMAGE_COLOR ); xformed = cvCreateImage( cvGetSize( img2orig ), IPL_DEPTH_8U, 3 ); cvReleaseImage( &img2orig ); img1orig = cvLoadImage( img1fname, CV_LOAD_IMAGE_COLOR); cvWarpPerspective( img1orig, xformed, H, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, cvScalarAll( 0 ) ); cvSaveImage( "xformed.jpg", xformed ); cvReleaseImage( &img1orig ); cvReleaseImage( &xformed ); // cvReleaseMat( &H ); } */ } kdtree_release( kd_root ); free( feat1 ); free( feat2 ); return 0; }
startree_t* startree_build(fitstable_t* intable, const char* racol, const char* deccol, // keep RA,Dec in the tag-along table? //anbool keep_radec, // KDT_DATA_*, KDT_TREE_* int datatype, int treetype, // KD_BUILD_* int buildopts, int Nleaf, char** args, int argc) { double* ra = NULL; double* dec = NULL; double* xyz = NULL; int N; startree_t* starkd = NULL; int tt; int d; double low[3]; double high[3]; qfits_header* hdr; qfits_header* inhdr; int i; if (!racol) racol = "RA"; if (!deccol) deccol = "DEC"; if (!datatype) datatype = KDT_DATA_U32; if (!treetype) treetype = KDT_TREE_U32; if (!buildopts) buildopts = KD_BUILD_SPLIT; if (!Nleaf) Nleaf = 25; ra = fitstable_read_column(intable, racol, TFITS_BIN_TYPE_D); if (!ra) { ERROR("Failed to read RA from column %s", racol); goto bailout; } dec = fitstable_read_column(intable, deccol, TFITS_BIN_TYPE_D); if (!dec) { ERROR("Failed to read RA from column %s", racol); goto bailout; } N = fitstable_nrows(intable); xyz = malloc(N * 3 * sizeof(double)); if (!xyz) { SYSERROR("Failed to malloc xyz array to build startree"); goto bailout; } radecdeg2xyzarrmany(ra, dec, xyz, N); free(ra); ra = NULL; free(dec); dec = NULL; starkd = startree_new(); if (!starkd) { ERROR("Failed to allocate startree"); goto bailout; } tt = kdtree_kdtypes_to_treetype(KDT_EXT_DOUBLE, treetype, datatype); starkd->tree = kdtree_new(N, 3, Nleaf); for (d=0; d<3; d++) { low[d] = -1.0; high[d] = 1.0; } kdtree_set_limits(starkd->tree, low, high); logverb("Building star kdtree...\n"); starkd->tree = kdtree_build(starkd->tree, xyz, N, 3, Nleaf, tt, buildopts); if (!starkd->tree) { ERROR("Failed to build star kdtree"); startree_close(starkd); starkd = NULL; goto bailout; } starkd->tree->name = strdup(STARTREE_NAME); inhdr = fitstable_get_primary_header(intable); hdr = startree_header(starkd); an_fits_copy_header(inhdr, hdr, "HEALPIX"); an_fits_copy_header(inhdr, hdr, "HPNSIDE"); an_fits_copy_header(inhdr, hdr, "ALLSKY"); an_fits_copy_header(inhdr, hdr, "JITTER"); an_fits_copy_header(inhdr, hdr, "CUTNSIDE"); an_fits_copy_header(inhdr, hdr, "CUTMARG"); an_fits_copy_header(inhdr, hdr, "CUTDEDUP"); an_fits_copy_header(inhdr, hdr, "CUTNSWEP"); //fits_copy_header(inhdr, hdr, "CUTBAND"); //fits_copy_header(inhdr, hdr, "CUTMINMG"); //fits_copy_header(inhdr, hdr, "CUTMAXMG"); BOILERPLATE_ADD_FITS_HEADERS(hdr); qfits_header_add(hdr, "HISTORY", "This file was created by the command-line:", NULL, NULL); fits_add_args(hdr, args, argc); qfits_header_add(hdr, "HISTORY", "(end of command line)", NULL, NULL); qfits_header_add(hdr, "HISTORY", "** History entries copied from the input file:", NULL, NULL); fits_copy_all_headers(inhdr, hdr, "HISTORY"); qfits_header_add(hdr, "HISTORY", "** End of history entries.", NULL, NULL); for (i=1;; i++) { char key[16]; int n; sprintf(key, "SWEEP%i", i); n = qfits_header_getint(inhdr, key, -1); if (n == -1) break; an_fits_copy_header(inhdr, hdr, key); } bailout: if (ra) free(ra); if (dec) free(dec); if (xyz) free(xyz); return starkd; }
void match::domatch(std::vector<SamePoint>& resultData) { const int nBlockSize = 512; int scale = 1; int nx1, ny1, nx2, ny2, nband1, nband2; uchar *pBuf = NULL; m_pImage->Open(_bstr_t(m_szPathNameL), modeRead); m_pImage->GetCols(&nx1); m_pImage->GetRows(&ny1); m_pImage->GetBandNum(&nband1); m_pImage->Close(); m_pImage->Open(_bstr_t(m_szPathNameR), modeRead); m_pImage->GetCols(&nx2); m_pImage->GetRows(&ny2); m_pImage->GetBandNum(&nband2); m_pImage->Close(); int mincr = /*max(max(max(nx1, ny1), nx2),ny2)*/(nx1+nx2+ny1+ny2)/4; while(mincr/scale >1024) { scale *= 2; } int nxsize1 = nx1/scale; int nysize1 = ny1/scale; int nxsize2 = nx2/scale; int nysize2 = ny2/scale; m_pImage->Open(_bstr_t(m_szPathNameL), modeRead); pBuf = new uchar[nxsize1*nysize1*nband1]; m_pImage->ReadImg(0, 0, nx1, ny1, pBuf, nxsize1, nysize1, nband1, 0, 0, nxsize1, nysize1, -1, 0); m_pImage->Close(); m_pImage->CreateImg(_bstr_t("templ.tif"), modeCreate, nxsize1, nysize1, Pixel_Byte, nband1, BIL, 0, 0, 1); m_pImage->WriteImg(0, 0, nxsize1, nysize1, pBuf, nxsize1, nysize1, nband1, 0, 0, nxsize1, nysize1, -1, 0); m_pImage->Close(); delete [] pBuf; m_pImage->Open(_bstr_t(m_szPathNameR), modeRead); pBuf = new uchar[nxsize2*nysize2*nband2]; m_pImage->ReadImg(0, 0, nx2, ny2, pBuf, nxsize2, nysize2, nband2, 0, 0, nxsize2, nysize2, -1, 0); m_pImage->Close(); m_pImage->CreateImg(_bstr_t("tempr.tif"), modeCreate, nxsize2, nysize2, Pixel_Byte, nband2, BIL, 0, 0, 1); m_pImage->WriteImg(0, 0, nxsize2, nysize2, pBuf, nxsize2, nysize2, nband2, 0, 0, nxsize2, nysize2, -1, 0); m_pImage->Close(); delete []pBuf; pBuf = NULL; sl.fetchFeatures("templ.tif"); sr.fetchFeatures("tempr.tif"); /*sl.fetchFeatures(m_szPathNameL); sr.fetchFeatures(m_szPathNameR);*/ Keypoint** nbrs; kd_node* kd_root; int nsize = sl.m_listKeyPoint.size(); int nsize2 = sr.m_listKeyPoint.size(); Keypoint* feat1 = (Keypoint*)malloc(nsize*sizeof(Keypoint)); std::list<Keypoint>::iterator temIte = sl.m_listKeyPoint.begin(); int i = 0; while(temIte != sl.m_listKeyPoint.end()) { feat1[i] = *temIte; ++i; ++temIte; } sl.m_listKeyPoint.clear(); Keypoint* feat2 = (Keypoint*)malloc(nsize2*sizeof(Keypoint)); temIte = sr.m_listKeyPoint.begin(); i = 0; while(temIte != sr.m_listKeyPoint.end()) { feat2[i] = *temIte; ++i; ++temIte; } sr.m_listKeyPoint.clear(); kd_root = kdtree_build(feat2, nsize2); int k = 0; double d0, d1; Keypoint* feat; int matchnum = 0; std::vector<SamePoint> sp; for (i = 0; i < nsize; ++i) { feat = feat1+i; k = kdtree_bbf_knn(kd_root, feat, 2, &nbrs, KDTREE_BBF_MAX_NN_CHKS); if (k == 2) { d0 = descr_dist_sq(feat, nbrs[0]); d1 = descr_dist_sq(feat, nbrs[1]); if (d0 < d1*NN_SQ_DIST_RATIO_THR) { sp.push_back(SamePoint(feat->dx, feat->dy, nbrs[0]->dx, nbrs[0]->dy)); ++matchnum; } } free(nbrs); } kdtree_release(kd_root); free(feat1); free(feat2); feat1 = NULL; feat2 = NULL; std::vector<double> matParameters; MatParamEstimator mpEstimator(5); int numForEstimate = 3; mpEstimator.leastSquaresEstimate(sp, matParameters); double usedData = Ransac<SamePoint, double>::compute(matParameters, &mpEstimator, sp, numForEstimate, resultData); sp.swap(std::vector<SamePoint>()); resultData.swap(std::vector<SamePoint>()); Pt lLeftTop(0, 0); Pt lRightBottom(nx1, ny1); double a = matParameters[0]; double b = matParameters[1]; double c = matParameters[2]*scale; double d = matParameters[3]; double e = matParameters[4]; double f = matParameters[5]*scale; std::list<Block> listDataBlock; for (int y = 0; y < ny1;) { if (y+nBlockSize < ny1) { for (int x = 0; x < nx1;) { if (x+nBlockSize < nx1) { Rec rect(a*x+b*y+c, a*(x+nBlockSize)+b*y+c, d*x+e*y+f, d*x+e*(y+nBlockSize)+f); if (rect.Intersects(Rec(0, nx2, 0, ny2))) { listDataBlock.push_back(Block(NULL, x, y, nBlockSize, nBlockSize)); } x += nBlockSize; } else { Rec rect(a*x+b*y+c, a*nx1+b*y+c, d*x+e*y+f, d*x+e*(y+nBlockSize)+f); if (rect.Intersects(Rec(0, nx2, 0, ny2))) { listDataBlock.push_back(Block(NULL, x, y, nx1-x, nBlockSize)); } x = nx1; } } y += nBlockSize; } else { for (int x = 0; x < nx1;) { if (x+nBlockSize < nx1) { Rec rect(a*x+b*y+c, a*(x+nBlockSize)+b*y+c, d*x+e*y+f, d*x+e*ny1+f); if (rect.Intersects(Rec(0, nx2, 0, ny2))) { listDataBlock.push_back(Block(NULL, x, y, nBlockSize, ny1-y)); } x += nBlockSize; } else { Rec rect(a*x+b*y+c, a*nx1+b*y+c, d*x+e*y+f, d*x+e*ny1+f); if (rect.Intersects(Rec(0, nx2, 0, ny2))) { listDataBlock.push_back(Block(NULL, x, y, nx1-x, ny1-y)); } x = nx1; } } y = ny1; } } int nBlockNumx = (nx2+nBlockSize-1)/nBlockSize; int nBlockNumy = (ny2+nBlockSize-1)/nBlockSize; int nBlockNum = nBlockNumx*nBlockNumy; std::vector<RBTree> vecKDTree(nBlockNum); std::list<Block>::iterator blockIte = listDataBlock.begin(); m_pImage->Open(_bstr_t(m_szPathNameL), modeRead); m_pImage2->Open(_bstr_t(m_szPathNameR), modeRead); int countblock = 0; std::list<SamePoint> listSP; std::vector<Keypoint> feature; std::vector<Keypoint> feature2; while(blockIte != listDataBlock.end()) { pBuf = new uchar[blockIte->nXSize*blockIte->nYSize*nband1]; m_pImage->ReadImg(blockIte->nXOrigin, blockIte->nYOrigin, blockIte->nXOrigin+blockIte->nXSize, blockIte->nYOrigin+blockIte->nYSize, pBuf, blockIte->nXSize, blockIte->nYSize, nband1, 0, 0, blockIte->nXSize, blockIte->nYSize, -1, 0); pixel_t* p = new pixel_t[blockIte->nXSize*blockIte->nYSize]; for (int y = 0; y < blockIte->nYSize; ++y) { for (int x = 0, m = 0; x < blockIte->nXSize*nband1; x += nband1, ++m) { double sum = 0; for (int n = 0; n < nband1; ++n) { sum += pBuf[y*blockIte->nXSize*nband1+x+n]; } p[y*blockIte->nXSize+m] = sum/(nband1*225.0); } } delete []pBuf; pBuf = NULL; sift(p, feature, blockIte->nXSize, blockIte->nYSize); p = NULL; std::vector<Keypoint>::iterator feaIte = feature.begin(); int count = 0; while(feaIte != feature.end()) { std::cout<<countblock<<"/"<<listDataBlock.size()<<":"<<count<<"/"<<feature.size()<<":"<<listSP.size()<<std::endl; ++count; feaIte->dx += blockIte->nXOrigin; feaIte->dy += blockIte->nYOrigin; int calx = int(feaIte->dx*a+feaIte->dy*b+c); int caly = int(feaIte->dx*d+feaIte->dy*e+f); int idx = calx/nBlockSize; int idy = caly/nBlockSize; if (idx >= nBlockNumx || idy >= nBlockNumy) { ++feaIte; continue; } int nBlockIndex = idy*nBlockNumx+idx; if (vecKDTree[nBlockIndex].num != 0 && vecKDTree[nBlockIndex].num < 50) { ++feaIte; continue; } if (vecKDTree[nBlockIndex].node == NULL) { int xo = idx*nBlockSize; int yo = idy*nBlockSize; int xsize = nBlockSize; int ysize = nBlockSize; if (idx == nBlockNumx-1) { xsize = nx2%nBlockSize; if (xsize == 0) { xsize = nBlockSize; } } if (idy == nBlockNumy-1) { ysize = ny2%nBlockSize; if (ysize == 0) { ysize = nBlockSize; } } pBuf = new uchar[xsize*ysize*nband2]; m_pImage2->ReadImg(xo, yo, xo+xsize, yo+ysize, pBuf, xsize, ysize, nband2, 0, 0, xsize, ysize, -1, 0); p = new pixel_t[xsize*ysize]; for(int y = 0; y < ysize; ++y) { for (int x = 0, m = 0; x < xsize*nband2; x += nband2, ++m) { double sum = 0; for (int n = 0; n < nband2; ++n) { sum += pBuf[y*xsize*nband2+x+n]; } p[y*xsize+m] = sum/(nband2*255.0); } } delete []pBuf; pBuf = NULL; sift(p, feature2, xsize, ysize); p = NULL; int nf2 = feature2.size(); vecKDTree[nBlockIndex].num = nf2; if (nf2 < 50) { ++feaIte; continue; } feat2 = (Keypoint*)malloc(nf2*sizeof(Keypoint)); std::vector<Keypoint>::iterator kIte2 = feature2.begin(); i = 0; while(kIte2 != feature2.end()) { kIte2->dx += xo; kIte2->dy += yo; feat2[i] = *kIte2; ++i; ++kIte2; } feature2.swap(std::vector<Keypoint>()); kd_root = kdtree_build(feat2, nf2); vecKDTree[nBlockIndex].node = kd_root; vecKDTree[nBlockIndex].feature = feat2; } k = kdtree_bbf_knn(vecKDTree[nBlockIndex].node, &(*feaIte), 2, &nbrs, KDTREE_BBF_MAX_NN_CHKS); if (k == 2) { d0 = descr_dist_sq(&(*feaIte), nbrs[0]); d1 = descr_dist_sq(&(*feaIte), nbrs[1]); if (d0 < d1*NN_SQ_DIST_RATIO_THR) { listSP.push_back(SamePoint(feaIte->dx, feaIte->dy, nbrs[0]->dx, nbrs[0]->dy)); } } free(nbrs); ++feaIte; } feature.swap(std::vector<Keypoint>()); std::vector<RBTree>::iterator kdIte = vecKDTree.begin(); while(kdIte != vecKDTree.end()) { if (kdIte->node != NULL) { free(kdIte->node); kdIte->node = NULL; free(kdIte->feature); kdIte->feature = NULL; } ++kdIte; } ++countblock; ++blockIte; } m_pImage->Close(); m_pImage2->Close(); std::vector<SamePoint> vecsp(std::make_move_iterator(std::begin(listSP)), std::make_move_iterator(std::end(listSP))); listSP.clear(); sp.swap(vecsp); mpEstimator.leastSquaresEstimate(sp, matParameters); if (sp.size() < 500) { usedData = Ransac<SamePoint, double>::compute(matParameters, &mpEstimator, sp, numForEstimate, resultData); } else { usedData = Ransac<SamePoint, double>::compute(matParameters, &mpEstimator, sp, numForEstimate, 0.5, 0.8, resultData); } std::cout<<usedData<<":"<<resultData.size()<<std::endl; sp.swap(std::vector<SamePoint>()); resultData.swap(std::vector<SamePoint>()); a = matParameters[0]; b = matParameters[1]; c = matParameters[2]; d = matParameters[3]; e = matParameters[4]; f = matParameters[5]; //mosaic Pt calrLeftTop; Pt calrRightBottom; calrLeftTop.x = lLeftTop.x*a+lLeftTop.y*b+c; calrLeftTop.y = lLeftTop.x*d+lLeftTop.y*e+f; calrRightBottom.x = lRightBottom.x*a+lRightBottom.y*b+c; calrRightBottom.y = lRightBottom.x*d+lRightBottom.y*e+f; Rec calRight(calrLeftTop.x, calrRightBottom.x, calrLeftTop.y, calrRightBottom.y); calRight.extend(); Rec Right(0, nx2, 0, ny2); Rec resultRec = Right.Union(calRight); Rec resultRectR = calRight.Intersected(Right); resultRectR.extend(); Pt callLeftTop; Pt callRightBottom; callLeftTop.y = (d/a*resultRectR.left-resultRectR.top+f-c*d/a)/(b*d/a-e); callLeftTop.x = (resultRectR.left-b*callLeftTop.y-c)/a; callRightBottom.y = (d/a*resultRectR.right-resultRectR.bottom+f-c*d/a)/(b*d/a-e); callRightBottom.x = (resultRectR.right-b*callRightBottom.y-c)/a; Rec resultRectL(callLeftTop.x, callRightBottom.x, callLeftTop.y, callRightBottom.y); resultRectL.extend(); m_pImage->CreateImg(_bstr_t("result.tif"), modeCreate, (int)resultRec.Width(), (int)resultRec.Height(), Pixel_Byte, nband1, BIL, 0, 0, 1); IImage* pImage = NULL; IImage* pImage2 = NULL; ::CoCreateInstance(CLSID_ImageDriver, NULL, CLSCTX_ALL, IID_IImage, (void**)&pImage); ::CoCreateInstance(CLSID_ImageDriver, NULL, CLSCTX_ALL, IID_IImage, (void**)&pImage2); pImage->Open(_bstr_t(m_szPathNameR), modeRead); pBuf = new uchar[nx2*nBlockSize*nband2]; for (int i = 0; i < ny2;) { if (i + nBlockSize < ny2) { pImage->ReadImg(0, i, nx2, i+nBlockSize, pBuf, nx2, nBlockSize, nband2, 0, 0, nx2, nBlockSize, -1, 0); m_pImage->WriteImg(int(0-resultRec.left), int(i-resultRec.top), int(nx2-resultRec.left), int(i+nBlockSize-resultRec.top), pBuf, nx2, nBlockSize, nband2, 0, 0, nx2, nBlockSize, -1, 0); i += nBlockSize; } else { pImage->ReadImg(0, i, nx2, ny2, pBuf, nx2, nBlockSize, nband2, 0, 0, nx2, ny2-i, -1, 0); m_pImage->WriteImg(int(0-resultRec.left), int(i-resultRec.top), int(nx2-resultRec.left), int(ny2-resultRec.top), pBuf, nx2, nBlockSize, nband2, 0, 0, nx2, ny2-i, -1, 0); i = ny2; } } pImage->Close(); delete []pBuf; pImage->Open(_bstr_t(m_szPathNameL), modeRead); pBuf = new uchar[nx1*nBlockSize*nband1]; for (int i = 0; i < calRight.Height();) { if (i+nBlockSize < calRight.Height()) { pImage->ReadImg(0, i, nx1, i+nBlockSize, pBuf, nx1, nBlockSize, nband1, 0, 0, nx1, nBlockSize, -1, 0); m_pImage->WriteImg(int(calRight.left-resultRec.left), int(calRight.top+i-resultRec.top), int(calRight.right-resultRec.left), int(calRight.top+i+nBlockSize-resultRec.top), pBuf, nx1, nBlockSize, nband1, 0, 0, nx1, nBlockSize, -1, 0); i += nBlockSize; } else { pImage->ReadImg(0, i, nx1, ny1, pBuf, nx1, nBlockSize, nband1, 0, 0, nx1, ny1-i, -1, 0); m_pImage->WriteImg(int(calRight.left-resultRec.left), int(calRight.top+i-resultRec.top), int(calRight.right-resultRec.left), int(calRight.bottom-resultRec.top), pBuf, nx1, nBlockSize, nband1, 0, 0, nx1, ny1-i, -1, 0); i = (int)calRight.Height(); } } pImage->Close(); delete []pBuf; pBuf = NULL; m_pImage->Close(); pImage->Open(_bstr_t(m_szPathNameL), modeRead); pImage2->Open(_bstr_t(m_szPathNameR), modeRead); m_pImage->Open(_bstr_t("result.tif"), modeReadWrite); pBuf = new uchar[nband1*(int)resultRectR.Width()*(int)resultRectR.Height()]; m_pImage->ReadImg(int(resultRectR.left-resultRec.left), int(resultRectR.top-resultRec.top), int(resultRectR.right-resultRec.left), int(resultRectR.bottom-resultRec.top), pBuf, (int)resultRectR.Width(), (int)resultRectR.Height(), nband1, 0, 0, (int)resultRectR.Width(), (int)resultRectR.Height(), -1, 0); uchar* pBufl = new uchar[nband1*(int)resultRectL.Width()*(int)resultRectL.Height()]; pImage->ReadImg((int)resultRectL.left, (int)resultRectL.top, (int)resultRectL.right, (int)resultRectL.bottom, pBufl, (int)resultRectL.Width(), (int) resultRectL.Height(), nband1, 0, 0, (int)resultRectL.Width(), (int)resultRectL.Height(), -1, 0); uchar* pBufr = new uchar[nband2*(int)resultRectR.Width()*(int)resultRectR.Height()]; pImage2->ReadImg((int)resultRectR.left, (int)resultRectR.top, (int)resultRectR.right, (int)resultRectR.bottom, pBufr, (int)resultRectR.Width(), (int)resultRectR.Height(), nband2, 0, 0, (int)resultRectR.Width(), (int)resultRectR.Height(), -1, 0); double lx, ly; for (int y = 0; y < (int)resultRectR.Height(); ++y) { for (int x = 0; x < (int)resultRectR.Width()*nband1; x += nband1) { ly = (d/a*(x+resultRectR.left)-(y+resultRectR.top)+f-c*d/a)/(b*d/a-e); lx = ((x+resultRectR.left)-b*ly-c)/a; if (ly < resultRectL.top || lx < resultRectL.left) { continue; } if (pBufl[(int)(ly-resultRectL.top)*(int)resultRectL.Width()*nband1+(int)(lx-resultRectL.left)] < 20 && pBufl[(int)(ly-resultRectL.top)*(int)resultRectL.Width()*nband1+(int)(lx-resultRectL.left)+1] < 20 && pBufl[(int)(ly-resultRectL.top)*(int)resultRectL.Width()*nband1+(int)(lx-resultRectL.left)+2] < 20) { for (int n = 0; n < nband2; ++n) { pBuf[y*(int)resultRectR.Width()*nband1+x+n] = pBufr[y*(int)resultRectR.Width()*nband2+x+n]; } } else if (pBufr[y*(int)resultRectR.Width()*nband1+x] < 20 && pBufr[y*(int)resultRectR.Width()*nband1+x+1]<20 && pBufr[y*(int)resultRectR.Width()*nband1+x+2]<20) { for (int n = 0; n < nband1; ++n) { pBuf[y*(int)resultRectR.Width()*nband1+x+n] = pBufl[(int)(ly-resultRectL.top)*(int)resultRectL.Width()*nband1+(int)(lx-resultRectL.left)+n]; } } else { for (int n = 0; n < nband1; ++n) { pBuf[y*(int)resultRectR.Width()*nband1+x+n] = (pBufl[(int)(ly-resultRectL.top)*(int)resultRectL.Width()*nband1+(int)(lx-resultRectL.left)+n] + pBufr[y*(int)resultRectR.Width()*nband2+x+n])/2; } } } } delete []pBufl; pBufl = NULL; delete []pBufr; pBufr = NULL; m_pImage->WriteImg(int(resultRectR.left-resultRec.left), int(resultRectR.top-resultRec.top), int(resultRectR.right-resultRec.left), int(resultRectR.bottom-resultRec.top), pBuf, (int)resultRectR.Width(), (int)resultRectR.Height(), nband1, 0, 0, (int)resultRectR.Width(), (int)resultRectR.Height(), -1, 0); delete []pBuf; pBuf = NULL; m_pImage->Close(); }