示例#1
0
    /** Generate points
     */
    static void makePoints( const SURF& surf,
                            std::vector<Point>& points )
    {
        const unsigned n1 =
            surf.numIntervals1() + (surf.periodic1() ? 0 : 1 );
        const unsigned n2 =
            surf.numIntervals2() + (surf.periodic2() ? 0 : 1 );
        
        for ( unsigned j = 0; j < n2; j++ ) {
            for ( unsigned i = 0; i < n1; i++ ) {
                points.push_back( surf.makePoint( i, j ) );
            }
        }

    }
示例#2
0
/*****************************************************************************
    *  @brief    : surfFeatureDetect
    *  @author   : Zhangle
    *  @date     : 2014/9/8 11:18
    *  @version  : ver 1.0
    *  @inparam  :
    *  @outparam :
*****************************************************************************/
void FeatureDetect::surfFeatureDetect(string inputImageName, string outputImageName,string outputTxtName) {
    Mat image = imread(inputImageName);
    Mat descriptors;
    vector<KeyPoint> keypoints;
    SURF surf;
    time_t beginTime = time(NULL);
    surf.detect(image,keypoints);
    time_t endTime = time(NULL);
    time_t runTime = endTime - beginTime;
    drawKeypoints(image,keypoints,image,Scalar(255,0,0));
    imwrite(outputImageName,image);
    ofstream outTxt(outputTxtName);
    outTxt << "SURF" << endl;
    outTxt << "影像尺寸:" << image.cols<<" * "<<image.rows<<endl;
    outTxt << "特征点数目:" << keypoints.size() <<"个"<< endl;
    outTxt << "提取特征点耗费时间:" << runTime << "s"<< endl;
    outTxt << "默认参数设置" << endl;
    outTxt.close();
}
示例#3
0
    /** Generate elements
     */
    static void makeElements( const SURF& surf,
                              std::vector<Element>& elements )
    {
        const unsigned n1 = surf.numIntervals1();
        const unsigned n2 = surf.numIntervals2();
        
        for ( unsigned j = 0; j < n2; j++ ) {
            for ( unsigned i = 0; i < n1; i++ ) {

                // following indices with boundary periodicity
                const std::size_t iNext =
                    ( i < n1 - 1 ? i+1 :
                      (surf.periodic1() ? 0 : i+1) );
                const std::size_t jNext = 
                    ( j < n2 - 1 ? j+1 :
                      (surf.periodic2() ? 0 : j+1) );

                // index shift to next line
                const unsigned stride =
                    n1 + static_cast<unsigned>(not surf.periodic1());
                
                // the four vertices of a quadrilateral
                const std::size_t i1 = j     * stride + i;
                const std::size_t i2 = j     * stride + iNext;
                const std::size_t i4 = jNext * stride + i;
                const std::size_t i3 = jNext * stride + iNext;

                if ( surf.withTriangles() ) {
                    // generate two triangles
                    Element tri1, tri2;
                    tri1.push_back( i1 );
                    tri1.push_back( i2 );
                    tri1.push_back( i3 );
                    tri2.push_back( i3 );
                    tri2.push_back( i4 );
                    tri2.push_back( i1 );
                    elements.push_back( tri1 );
                    elements.push_back( tri2 );
                
                }
                else {
                    // generate a quadrilateral
                    Element quad;
                    quad.push_back( i1 );
                    quad.push_back( i2 );
                    quad.push_back( i3 );
                    quad.push_back( i4 );
                    elements.push_back( quad );
                }
            }
        }
        return;
    }
//-----------------------------------【main( )函数】--------------------------------------------
//   描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main( int argc, char** argv )
{
	//【0】改变console字体颜色    
	system("color 4F");    

	//【0】显示帮助文字  
	ShowHelpText();  

	//【1】载入源图片
	Mat img_1 = imread("1.jpg", 1 );
	Mat img_2 = imread( "2.jpg", 1 );
	if( !img_1.data || !img_2.data ) { printf("读取图片image0错误~! \n"); return false; }  

	//【2】利用SURF检测器检测的关键点
	int minHessian = 300;
	SURF detector( minHessian );
	std::vector<KeyPoint> keypoints_1, keypoints_2;
	detector.detect( img_1, keypoints_1 );
	detector.detect( img_2, keypoints_2 );

	//【3】计算描述符(特征向量)
	SURF extractor;
	Mat descriptors_1, descriptors_2;
	extractor.compute( img_1, keypoints_1, descriptors_1 );
	extractor.compute( img_2, keypoints_2, descriptors_2 );

	//【4】采用FLANN算法匹配描述符向量
	FlannBasedMatcher matcher;
	std::vector< DMatch > matches;
	matcher.match( descriptors_1, descriptors_2, matches );
	double max_dist = 0; double min_dist = 100;

	//【5】快速计算关键点之间的最大和最小距离
	for( int i = 0; i < descriptors_1.rows; i++ )
	{
		double dist = matches[i].distance;
		if( dist < min_dist ) min_dist = dist;
		if( dist > max_dist ) max_dist = dist;
	}
	//输出距离信息
	printf("> 最大距离(Max dist) : %f \n", max_dist );
	printf("> 最小距离(Min dist) : %f \n", min_dist );

	//【6】存下符合条件的匹配结果(即其距离小于2* min_dist的),使用radiusMatch同样可行
	std::vector< DMatch > good_matches;
	for( int i = 0; i < descriptors_1.rows; i++ )
	{ 
		if( matches[i].distance < 2*min_dist )
		{ good_matches.push_back( matches[i]); }
	}

	//【7】绘制出符合条件的匹配点
	Mat img_matches;
	drawMatches( img_1, keypoints_1, img_2, keypoints_2,
		good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
		vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );

	//【8】输出相关匹配点信息
	for( int i = 0; i < good_matches.size(); i++ )
	{ printf( ">符合条件的匹配点 [%d] 特征点1: %d  -- 特征点2: %d  \n", i, good_matches[i].queryIdx, good_matches[i].trainIdx ); }

	//【9】显示效果图
	imshow( "匹配效果图", img_matches );

	//按任意键退出程序
	waitKey(0);
	return 0;
}
示例#5
0
/** @function main */
int matchKeypoints( int argc, char** argv )
{
//  if( argc != 3 )
//  { readme(); return -1; }
  cv::initModule_nonfree();

  Mat img_1 = imread( argv[1], CV_LOAD_IMAGE_GRAYSCALE );
  Mat img_2 = imread( argv[2], CV_LOAD_IMAGE_GRAYSCALE );
  Codebook codebook;
  //codebook.readInCSV(string(argv[3]));

  if( !img_1.data || !img_2.data )
  { std::cout<< " --(!) Error reading images " << std::endl; return -1; }

  //-- Step 1: Detect the keypoints using SURF Detector
  int minHessian = 15000;

  //SurfFeatureDetector detector( minHessian);
  SURF* detector = new SURF(minHessian,1,4,true,true);

  std::vector<KeyPoint> keypoints_1, keypoints_2;

  assert(img_1.size[0]>0 && img_1.size[1]>0 && img_2.size[0]>0 && img_2.size[1]>0);
  
  (*detector)( img_1, Mat(), keypoints_1 );
  (*detector)( img_2, Mat(), keypoints_2 );
  
  Mat img_keypoints_1; Mat img_keypoints_2;
//  drawKeypoints( img_1, keypoints_1, img_keypoints_1, Scalar::all(-1), DrawMatchesFlags::DEFAULT );
//  drawKeypoints( img_2, keypoints_2, img_keypoints_2, Scalar::all(-1), DrawMatchesFlags::DEFAULT );
  cvtColor(img_1,img_keypoints_1,CV_GRAY2RGB);
  for (KeyPoint k :keypoints_1)
  {
//      circle(img_keypoints_1,k.pt,k.size,Scalar(rand()%256,rand()%256,rand()%256));
//      cout<<k.size<<endl;
      Rect rec(k.pt.x-(k.size/2),k.pt.y-(k.size/2),k.size,k.size);
      rectangle(img_keypoints_1,rec,Scalar(rand()%256,rand()%256,rand()%256));
  }
  
  cvtColor(img_2,img_keypoints_2,CV_GRAY2RGB);
  for (KeyPoint k :keypoints_2)
  {
//      circle(img_keypoints_2,k.pt,k.size,Scalar(rand()%256,rand()%256,rand()%256));
      Rect rec(k.pt.x-(k.size/2),k.pt.y-(k.size/2),k.size,k.size);
      rectangle(img_keypoints_2,rec,Scalar(rand()%256,rand()%256,rand()%256));
  }
  
  
    //-- Show detected (drawn) keypoints
    imshow("Keypoints 1", img_keypoints_1 );
    imshow("Keypoints 2", img_keypoints_2 );
    waitKey(0);

  //-- Step 2: Calculate descriptors (feature vectors)
    //SurfDescriptorExtractor extractor;
  
    Mat descriptors_1, descriptors_2;
  
    detector->compute( img_1, keypoints_1, descriptors_1 );
    detector->compute( img_2, keypoints_2, descriptors_2 );
  
    //-- Step 3: Matching descriptor vectors using FLANN matcher
    FlannBasedMatcher matcher;
    std::vector< std::vector< DMatch > > matches;
    matcher.knnMatch( descriptors_1, descriptors_2, matches, 10 );
  
    double max_dist = 0; double min_dist = 100;
  
    //-- Quick calculation of max and min distances between keypoints
    for( int i = 0; i < matches.size(); i++ )
    {
        for (int j=0; j < matches[i].size(); j++)
        {
            double dist = matches[i][j].distance;
            if( dist < min_dist ) min_dist = dist;
            if( dist > max_dist ) max_dist = dist;
        }
    }
  
    printf("-- Max dist : %f \n", max_dist );
    printf("-- Min dist : %f \n", min_dist );
  
    //-- Draw only "good" matches (i.e. whose distance is less than 2*min_dist,
    //-- or a small arbitary value ( 0.02 ) in the event that min_dist is very
    //-- small)
    //-- PS.- radiusMatch can also be used here.
    std::vector< DMatch > good_matches;
  
    for( int i = 0; i < matches.size(); i++ )
    {
        for (int j=0; j < matches[i].size(); j++)
            //if( matches[i][j].distance <= max(2*min_dist, 0.02) )
            if( matches[i][j].distance <= max((max_dist-min_dist)/4.0 + min_dist, 0.02) )
            { good_matches.push_back( matches[i][j]); }
            else
                printf("discard(%d,%d)\n",i,j);
    }
  
    //-- Draw only "good" matches
    Mat img_matches;
    drawMatches( img_1, keypoints_1, img_2, keypoints_2,
                 good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
                 vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
  
    //-- Show detected matches
    imshow( ".... Matches", img_matches );
  
    for( int i = 0; i < (int)good_matches.size(); i++ )
    { printf( "-- .... Match [%d] Keypoint 1: %d  -- Keypoint 2: %d  \n", i, good_matches[i].queryIdx, good_matches[i].trainIdx ); }
  
    waitKey(0);
    
//    vector<Point2f> corners;
//      double qualityLevel = 0.01;
//      double minDistance = 10;
//      int blockSize = 3;
//      bool useHarrisDetector = false;
//      double k = 0.04;
//      int maxCorners = 23;
//      int maxTrackbar = 100;
//    goodFeaturesToTrack( src_gray,
//                   corners,
//                   maxCorners,
//                   qualityLevel,
//                   minDistance,
//                   Mat(),
//                   blockSize,
//                   useHarrisDetector,
//                   k );
    
  return 0;
  }
int main(int argc, char* argv[])
{
	//video input
	string videoName("A_kind_of_a_Show.avi");
	VideoCapture capture(videoName);
	if (!capture.isOpened())
	{
		cout << "!capture.isOpened()";
		return -1;
	}

	//path list
	vector<vector<Point2f>> pathList;
	vector<int> kpIdx2pathListIdx;
	
	vector<KeyPoint> kpTrackedPrev;
	Mat desTrackedPrev;
	vector<KeyPoint> kpEdgePrev;
	Mat desEdgePrev;

	//firstFrame init
	Mat firstFrame;
	Mat frame, framePrev;
	capture.read(firstFrame);
	keypointDetectorAnddescriptor.detect(firstFrame, kpTrackedPrev);
	keypointDetectorAnddescriptor.compute(firstFrame, kpTrackedPrev, desTrackedPrev);
	getEdgeKeypoint(firstFrame.cols, firstFrame.rows, 0.25,
		kpTrackedPrev, desTrackedPrev,
		kpEdgePrev, desEdgePrev);
	for (int i = 0; i < kpTrackedPrev.size(); ++i)
	{
		pathList.push_back(vector<Point2f>());
		pathList[i].push_back(kpTrackedPrev[i].pt);
		kpIdx2pathListIdx.push_back(i);
	}
	firstFrame.copyTo(framePrev);

	//video writer
	VideoWriter vw("result.avi", CV_FOURCC('M', 'J', 'P', 'G'), 12, Size(firstFrame.cols, firstFrame.rows));
	if (!vw.isOpened())
		return -1;

	//frame
	vector<KeyPoint> kpCur;
	Mat desCur;
	int frameIdx = 0;

	//processing
	while (capture.read(frame))
	{
		++frameIdx;

		keypointDetectorAnddescriptor.detect(frame, kpCur);
		keypointDetectorAnddescriptor.compute(frame, kpCur, desCur);

		//edge keypoint matching for homography
		vector<Point2f> ptEdgeCurMatched;
		vector<Point2f> ptEdgePrevMatched;
		vector<vector<DMatch>> vvmatchs;
		matcher.knnMatch(desEdgePrev, desCur, vvmatchs, 2);
		for (int i = 0; i < vvmatchs.size(); ++i)
		{
			if (vvmatchs[i][0].distance < vvmatchs[i][1].distance * 0.8)
			{
				ptEdgeCurMatched.push_back(kpCur[vvmatchs[i][0].trainIdx].pt);
				ptEdgePrevMatched.push_back(kpEdgePrev[vvmatchs[i][0].queryIdx].pt);
			}
		}

		//findHomography
		Mat h = findHomography(ptEdgePrevMatched,ptEdgeCurMatched, RANSAC);
		cout << h << endl;
		
		// camera movement compensation
		for (vector<Point2f>& path : pathList){
			perspectiveTransform(path, path, h);
		}

		Mat warpedframe;
		warpPerspective(framePrev, warpedframe, h, frame.size());
		imshow("frame", frame);
		imshow("prev", framePrev);
		imshow("warpedframe", warpedframe);

		getEdgeKeypoint(frame.cols, frame.rows, 0.25,
			kpCur, desCur,
			kpEdgePrev, desEdgePrev);
		frame.copyTo(framePrev);

		//keypoint tracking for pathlist
		vector<int> kpIdx2pathListIdxTemp;
		vector<KeyPoint> kpTrackedCur;
		Mat desTrackedCur;
		set<int> curMatchedKpIdxSet;
		matcher.knnMatch(desTrackedPrev, desCur, vvmatchs, 2);
		for (int i = 0; i < vvmatchs.size(); ++i)
		{
			if (vvmatchs[i][0].distance < vvmatchs[i][1].distance * 0.6)
			{
				pathList[kpIdx2pathListIdx[i]].push_back(kpCur[vvmatchs[i][0].trainIdx].pt);
				kpTrackedCur.push_back(kpCur[vvmatchs[i][0].trainIdx]);
				desTrackedCur.push_back(desCur.row(vvmatchs[i][0].trainIdx));
				kpIdx2pathListIdxTemp.push_back(kpIdx2pathListIdx[i]);
				curMatchedKpIdxSet.insert(vvmatchs[i][0].trainIdx);
			}
		}
		if (frameIdx%5==0)
		{
			//add new keypoint
			for (int i = 0; i < kpCur.size(); ++i)
			{
				if (curMatchedKpIdxSet.find(i) == curMatchedKpIdxSet.end()){
					kpTrackedCur.push_back(kpCur[i]);
					desTrackedCur.push_back(desCur.row(i));
					pathList.push_back(vector<Point2f>());
					pathList.rbegin()->push_back(kpCur[i].pt);
					kpIdx2pathListIdxTemp.push_back(pathList.size() - 1);
				}
			}
		}

		kpIdx2pathListIdx = kpIdx2pathListIdxTemp;
		kpTrackedPrev = kpTrackedCur;
		desTrackedCur.copyTo(desTrackedPrev);
		Mat show;
		drawPathList(frame, show, pathList);
		imshow("pathlist", show);
		waitKey(1);

		vw << show;
	}
	vw.release();
	//uniform
	for (vector<Point2f>& path : pathList)
	{
		for (Point2f& pt : path)
		{
			pt.x /= firstFrame.cols;
			pt.y /= firstFrame.rows;
		}
	}

	vector<double> motionHist;
	calMotionHist(pathList, motionHist);
	cout << "h : " << endl;
	for (double h : motionHist)
		cout << h << " ";
	cout << endl;
	return 1;
}
示例#7
0
文件: test.cpp 项目: Xalos/Poke-dex
int main(int argc, char* argv[])
{

SURF extractor;
Mat train_descr;
SurfFeatureDetector detector(700);

BFMatcher match(NORM_L2);	//Try to replace with FLANN
vector<vector<DMatch> > matches;

//namedWindow("Image", CV_WINDOW_AUTOSIZE );

vector<KeyPoint> keypoints;
Mat descriptors;

FileStorage train;
train.open("Train.xml", FileStorage::READ);

int correct = 0;
float mean_error = 0;
float min = 0;
int m = 0;

string name = argv[1];

for(int x = 2;x<argc;x++)
{
Mat img = imread(argv[x]);
detector.detect(img, keypoints);
//drawKeypoints(img,keypoints,img,255);
//imshow("Image",img);
//waitKey(0);
extractor.compute(img, keypoints, descriptors);

//Compute errors

mean_error = 0;
min = 0;
m = 0;

for(int n = 0; n <CLASSES; n++)
{
train[set[n]]>>train_descr;
match.knnMatch(descriptors,train_descr,matches,NEIGHBOURS);

for(int j=0;j<NEIGHBOURS;j++)
for(int i=0;i<KEYPOINTS;i++)
{
mean_error+=matches.at(i).at(j).distance;
}

mean_error = mean_error/(NEIGHBOURS*KEYPOINTS);

if(n==0)
min = mean_error;

if(min>mean_error)
{
min = mean_error;
m = n;
}

}

if(!name.compare(set[m]))
correct+=1;
}


cout<<"Classification accuracy for "<<name<<" is:"<<(((float)correct)/(argc-2)) * 100<<endl;

train.release();

return 0;
}