コード例 #1
0
ファイル: bow.cpp プロジェクト: shingt/cvutils
  //
  // createBoW
  //
  // @param[in] feature_vectors...extracted features.
  // 複数の特徴ベクトルであることに注意
  // @param[in] codebook...calculated codebook.
  // @param[out] bow...output bag-of-words.
  //
  void createBoW (
      const cv::Mat &feature_vectors, 
      const codebook &codebook, 
      std::vector<float> &bow)
  {
    // 各特徴ベクトルに関して最近傍のvisual-wordを見つけて投票
    int num_feature_vectors = feature_vectors.rows;
    int codebook_size = codebook.rows;
    assert (codebook_size != 0);

    // 最も近いvisual-wordのインデックス
    cv::Mat indices 
      = cv::Mat::zeros (num_feature_vectors, codebook_size, CV_32SC1); 
    // その距離
    cv::Mat dists 
      = cv::Mat::zeros (num_feature_vectors, codebook_size, CV_64FC1);  

    // kD-tree
    cv::flann::Index flannIndex (codebook, cv::flann::KDTreeIndexParams ());
    cv::flann::SearchParams searchParams = cv::flann::SearchParams ();

    // Nearest Neighbor
    flannIndex.knnSearch (feature_vectors, indices, dists, 
        codebook_size, searchParams);

    // Create histogram
    std::vector<int> hist (codebook.rows);
    std::fill (hist.begin (), hist.end (), 0);
    for (int j = 0; j < indices.rows; j++) {
      // 現在は最近傍法なのでindicesの最初の要素だけを見ればよい
      int idx = indices.at<int> (j, 0);     // FIXME: 画素アクセス
      hist[idx]++;
    }

    // Normalization
    // 局所特徴の総数でヒストグラムの各binを割る
    assert (bow.empty ());
    for (int i = 0; i < hist.size (); ++i) {
      float val_normalized = (float) hist[i] / (float) num_feature_vectors;
      bow.push_back (val_normalized);
    }

    // (0, 1]の間で正規化する
    SG::normalizeVector (bow); 
  }
コード例 #2
0
WeightedGraph kNearestGraph(const Mat_<Vec3f> &image, const Mat_<float> mask, int k, double (*simFunc)(const Mat&, const Mat&), bool bidirectional) {
	vector<int> indexToVertex;
	Mat features = pixelFeatures(image, mask, indexToVertex, positionHueFeature, 3);
	flann::Index flannIndex(features, flann::KMeansIndexParams(16, 3));
	WeightedGraph nnGraph(image.rows * image.cols);
	set<pair<int,int> > edges;

	// for each feature, determine the k nearest neighbors and add them
	// as edges to the graph.
	for (int i = 0; i < features.rows; i++) {
		vector<int> indices(k + 1);
		vector<float> distances(k + 1);

		flannIndex.knnSearch(features.row(i), indices, distances, k + 1);
		int source = indexToVertex[i];

		for (int j = 0; j < k + 1; j++) {
			if (indices[j] != i) {
				int destination = indexToVertex[indices[j]];
				
				int first = min(source, destination);
				int second = max(source, destination);

				if (edges.find(pair<int,int>(first, second)) == edges.end()) {
					float weight = (float)simFunc(features.row(i), features.row(indices[j]));

					edges.insert(pair<int,int>(first, second));
					nnGraph.addEdge(source, destination, weight);

					if (bidirectional) {
						nnGraph.addEdge(destination, source, weight);
					}
				}
			}
		}
	}

	return nnGraph;
}
コード例 #3
0
bool ofxFeatureFinder::detectObject(ofxFeatureFinderObject object, cv::Mat &homography) {
    ////////////////////////////
    // NEAREST NEIGHBOR MATCHING USING FLANN LIBRARY (included in OpenCV)
    //////////////////////////
    cv::Mat results;
    cv::Mat dists;
    int k=2; // find the 2 nearest neighbors

    // assume it is CV_32F
    // Create Flann KDTree index
    cv::flann::Index flannIndex(imageDescriptors, cv::flann::KDTreeIndexParams(), cvflann::FLANN_DIST_EUCLIDEAN);
    results = cv::Mat(object.descriptors.rows, k, CV_32SC1); // Results index
    dists = cv::Mat(object.descriptors.rows, k, CV_32FC1); // Distance results are CV_32FC1
        
    // search (nearest neighbor)
    flannIndex.knnSearch(object.descriptors, results, dists, k, cv::flann::SearchParams() );

    
    // Find correspondences by NNDR (Nearest Neighbor Distance Ratio)
    float nndrRatio = 0.6;
    std::vector<cv::Point2f> mpts_1, mpts_2; // Used for homography
    std::vector<int> indexes_1, indexes_2; // Used for homography
    std::vector<uchar> outlier_mask;  // Used for homography
    for(unsigned int i=0; i<object.descriptors.rows; ++i)
    {
        // Check if this descriptor matches with those of the objects
        // Apply NNDR
        if(dists.at<float>(i,0) <= nndrRatio * dists.at<float>(i,1))
        {
            mpts_1.push_back(object.keypoints.at(i).pt);
            indexes_1.push_back(i);
            
            mpts_2.push_back(imageKeypoints.at(results.at<int>(i,0)).pt);
            indexes_2.push_back(results.at<int>(i,0));
        }
    }
    
    // FIND HOMOGRAPHY

    if(mpts_1.size() >= minMatchCount)
    {
        homography = findHomography(mpts_1, mpts_2, cv::RANSAC, 1.0, outlier_mask);

        uint inliers=0, outliers=0;
        for(unsigned int k=0; k<mpts_1.size(); ++k)
        {
            if(outlier_mask.at(k))
            {
                ++inliers;
            }
            else
            {
                ++outliers;
            }
        }

        cout << inliers << " in / " << outliers << " out" << endl;
        
        return true;
    }
    
    return false;
}
void locallyLinearEmbeddings(const Mat_<float> &samples, int outDim, Mat_<float> &embeddings, int k) {
	assert(outDim < samples.cols);
	assert(k >= 1);
	Mat_<int> nearestNeighbors(samples.rows, k);

	// determining k nearest neighbors for each sample
	flann::Index flannIndex(samples, flann::LinearIndexParams());

	for (int i = 0; i < samples.rows; i++) {
		Mat_<int> nearest;
		Mat dists;

		flannIndex.knnSearch(samples.row(i), nearest, dists, k + 1);
		nearest.colRange(1, nearest.cols).copyTo(nearestNeighbors.row(i));
	}

	// determining weights for each sample
	vector<Triplet<double> > tripletList;
	tripletList.reserve(samples.rows * k);

	for (int i = 0; i < samples.rows; i++) {
		Mat_<double> C(k,k);

		for (int u = 0; u < k; u++) {
			for (int v = u; v < k; v++) {
				C(u,v) = (samples.row(i) - samples.row(nearestNeighbors(i,u))).dot(samples.row(i) - samples.row(nearestNeighbors(i,v)));
				C(v,u) = C(u,v);
			}
		}

		// regularize when the number of neighbors is greater than the input
		// dimension
		if (k > samples.cols) {
			C = C + Mat_<double>::eye(k,k) * 10E-3 * trace(C)[0];
		}

		Map<MatrixXd,RowMajor> eigC((double*)C.data, C.rows, C.cols);

		LDLT<MatrixXd> solver(eigC);

		Mat_<double> weights(k,1);
		Map<MatrixXd,RowMajor> eigWeights((double*)weights.data, weights.rows, weights.cols);

		eigWeights = solver.solve(MatrixXd::Ones(k,1));	

		Mat_<double> normWeights;

		double weightsSum = sum(weights)[0];

		if (weightsSum == 0) {
			cout<<"error: cannot reconstruct point "<<i<<" from its neighbors"<<endl;
			exit(EXIT_FAILURE);
		}

		normWeights = weights / weightsSum;

		for (int j = 0; j < k; j++) {
			tripletList.push_back(Triplet<double>(nearestNeighbors(i,j), i, normWeights(j)));
		}
	}

	SparseMatrix<double> W(samples.rows, samples.rows);

	W.setFromTriplets(tripletList.begin(), tripletList.end());

	// constructing vectors in lower dimensional space from the weights
	VectorXd eigenvalues;
	MatrixXd eigenvectors;

	LLEMult mult(&W);

	symmetricSparseEigenSolver(samples.rows, "SM", outDim + 1, samples.rows, eigenvalues, eigenvectors, mult);
	embeddings = Mat_<double>(samples.rows, outDim);

	if (DEBUG_LLE) {
		cout<<"actual eigenvalues : "<<eigenvalues<<endl;
		cout<<"actual : "<<endl<<eigenvectors<<endl;

		MatrixXd denseW(W);
		MatrixXd tmp = MatrixXd::Identity(W.rows(), W.cols()) - denseW;
		MatrixXd M = tmp.transpose() * tmp;
		SelfAdjointEigenSolver<MatrixXd> eigenSolver(M);
		MatrixXd expectedEigenvectors = eigenSolver.eigenvectors();

		cout<<"expected eigenvalues : "<<eigenSolver.eigenvalues()<<endl;
		cout<<"expected : "<<endl<<expectedEigenvectors<<endl;
	}

	for (int i = 0; i < samples.rows; i++) {
		for (int j = 0; j < outDim; j++) {
			embeddings(i,j) = eigenvectors(i, j + 1);
		}
	}
}
コード例 #5
0
// Main function, defines the entry point for the program.
int main( int argc, char** argv )
{

    // Structure for getting video from camera or avi
    CvCapture* capture = 0;

    // Images to capture the frame from video or camera or from file
    IplImage *frame, *frame_copy = 0;

    // Input file name for avi or image file.
    const char* vectorList;
    const char* testImage;

    // Check for the correct usage of the command line
    if( argc == 2 )
    {
        //vectorList = argv[1];
        testImage = argv[1];
    }
    else
    {
        fprintf( stderr, "Usage: eigenDecomp testImage\n" );
        return -1;
    }

    // Allocate the memory storage
    storage = cvCreateMemStorage(0);

    // Create a new named window with title: result
    cvNamedWindow( "result", 1 );

    std::vector<IplImage*> images;
    std::vector<char*> labels;

    //Load Labels
    printf("Loading Labels...  ");
    FILE* f = fopen( "labels.txt", "rt" );
    if( f )
    {
        char buf[100+1];

        // Get the line from the file
        while( fgets( buf, 100, f ) )
        {

            // Remove the spaces if any, and clean up the name
            int len = (int)strlen(buf);
            while( len > 0 && isspace(buf[len-1]) )
                len--;
            buf[len] = '\0';

            char* str = (char*)malloc(sizeof(char)*100);
            memcpy(str, buf, 100);
            labels.push_back(str);
        }
        // Close the file
        fclose(f);
        printf("%d Labels loaded.\n", labels.size());
    } else
        printf("Failed.\n");

    //Load Eigenvectors:
    printf("Loading Eigenvectors...  ");
    CvFileStorage* fs2 = cvOpenFileStorage("eigenvectors.yml", NULL, CV_STORAGE_READ);
    char vectorname[50];
    CvFileNode* vectorloc = cvGetFileNodeByName(fs2, NULL, "vector0");
    for(int i = 1; vectorloc != NULL; i++) {
        images.push_back((IplImage*)cvRead(fs2, vectorloc, &cvAttrList(0,0)));
        //printf("pushed %s\n", vectorname);
        sprintf(vectorname, "vector%d", i);
        vectorloc = cvGetFileNodeByName(fs2, NULL, vectorname);
    }
    //cvReleaseFileStorage(&fs2); This may delete the images
    printf("%d Eigenvectors (and 1 average) loaded.\n", images.size()-1);

    //TODO: unfix this number! - Done!
    //printf("FLANN DIMS: %d, %d\n", 165, images.size());
    //cv::Mat mat( 165, images.size(), CV_32F );
    //flann::Matrix<float> flannmat;
    //flann::load_from_file(flannmat, "flann.dat", "flann.dat");
    //flann::Index::Index flannIndex(flannmat, flann::LinearIndexParams());
    printf("Loading Nearest Neighbor Matrix...  ");
    CvMat* flannmat;
    CvFileStorage* fs = cvOpenFileStorage("nn.yml", NULL, CV_STORAGE_READ);
    flannmat = (CvMat*)cvRead(fs, cvGetFileNodeByName(fs, NULL, "data"), &cvAttrList(0,0));
    //cvReleaseFileStorage(&fs); This will delete the matrix
    printf("Done. DIMS: %d, %d\n", flannmat->rows, flannmat->cols);
    cv::flann::Index::Index flannIndex(flannmat, cv::flann::LinearIndexParams());

    int nn_dims = flannmat->cols; //number of nearest neighbor dimensions available
    int projection_dims = images.size()-1; //number of dimensions to project into eigenspace.

    IplImage* eigenArray[projection_dims];

    IplImage* avgImage = images[0];
    for(int i = 0; i < projection_dims; i++) {
        eigenArray[i] = images[i+1];
    }

    //load test image
    printf("Loading Test Image...\n");
    IplImage* testImg = cvLoadImage(testImage, CV_LOAD_IMAGE_GRAYSCALE);
    float projection[projection_dims];

    // Project the test image onto the PCA subspace
    printf("Conducting Eigen Decomposite...\n");
    cvEigenDecomposite(
        testImg, //test object
        projection_dims, //number of eigen vectors
        (void*)eigenArray, //eigenVectors
        0, 0, //ioflags, user callback data
        avgImage, //root eigen vector
        projection);


    //print projection
    //printf("Eigenvector Coefficents:\n");
    //for(int i = 0; i < projection_dims; i++)
    //printf("%5f ", projection[i]);
    //printf("\n");

    int neighbors = 10; //to test against

    std::vector<float> proj(nn_dims);
    std::vector<float> dists(neighbors);
    std::vector<int> indicies(neighbors);
    for(int i = 0; i < nn_dims; i++)
        proj[i] = projection[i];

    flannIndex.knnSearch(proj, indicies, dists, neighbors, NULL);
    for(int i = 0; i < neighbors; i++)
        printf("Index Match0: %4d, dist: %13.3f, Label: %s\n",
               indicies[i], dists[i], labels[indicies[i]]);

    // Destroy the window previously created with filename: "result"
    cvDestroyWindow("result");
    printf("Done.\n");
    // return 0 to indicate successfull execution of the program
    return 0;
}
コード例 #6
0
ファイル: main.cpp プロジェクト: chagge/find-object
int main(int argc, char * argv[])
{
	bool quiet = false;
	int method = mTotal; //total matches
	if(argc<3)
	{
		printf("Two images required!\n");
		showUsage();
	}
	else if(argc>3)
	{
		for(int i=1; i<argc-2; ++i)
		{
			if(std::string(argv[i]).compare("-inliers") == 0)
			{
				method = mInliers;
			}
			else if(std::string(argv[i]).compare("-quiet") == 0)
			{
				quiet = true;
			}
			else
			{
				printf("Option %s not recognized!", argv[1]);
				showUsage();
			}
		}
	}


	//Load as grayscale
	cv::Mat objectImg = cv::imread(argv[argc-2], cv::IMREAD_GRAYSCALE);
	cv::Mat sceneImg = cv::imread(argv[argc-1], cv::IMREAD_GRAYSCALE);

	int value = 0;
	if(!objectImg.empty() && !sceneImg.empty())
	{
		std::vector<cv::KeyPoint> objectKeypoints;
		std::vector<cv::KeyPoint> sceneKeypoints;
		cv::Mat objectDescriptors;
		cv::Mat sceneDescriptors;

		////////////////////////////
		// EXTRACT KEYPOINTS
		////////////////////////////
		cv::SIFT sift;
		sift.detect(objectImg, objectKeypoints);
		sift.detect(sceneImg, sceneKeypoints);

		////////////////////////////
		// EXTRACT DESCRIPTORS
		////////////////////////////
		sift.compute(objectImg, objectKeypoints, objectDescriptors);
		sift.compute(sceneImg, sceneKeypoints, sceneDescriptors);

		////////////////////////////
		// NEAREST NEIGHBOR MATCHING USING FLANN LIBRARY (included in OpenCV)
		////////////////////////////
		cv::Mat results;
		cv::Mat dists;
		std::vector<std::vector<cv::DMatch> > matches;
		int k=2; // find the 2 nearest neighbors

		// Create Flann KDTree index
		cv::flann::Index flannIndex(sceneDescriptors, cv::flann::KDTreeIndexParams(), cvflann::FLANN_DIST_EUCLIDEAN);
		results = cv::Mat(objectDescriptors.rows, k, CV_32SC1); // Results index
		dists = cv::Mat(objectDescriptors.rows, k, CV_32FC1); // Distance results are CV_32FC1

		// search (nearest neighbor)
		flannIndex.knnSearch(objectDescriptors, results, dists, k, cv::flann::SearchParams() );

		////////////////////////////
		// PROCESS NEAREST NEIGHBOR RESULTS
		////////////////////////////

		// Find correspondences by NNDR (Nearest Neighbor Distance Ratio)
		float nndrRatio = 0.6;
		std::vector<cv::Point2f> mpts_1, mpts_2; // Used for homography
		std::vector<int> indexes_1, indexes_2; // Used for homography
		std::vector<uchar> outlier_mask;  // Used for homography
		// Check if this descriptor matches with those of the objects

		for(int i=0; i<objectDescriptors.rows; ++i)
		{
			// Apply NNDR
			if(dists.at<float>(i,0) <= nndrRatio * dists.at<float>(i,1))
			{
				mpts_1.push_back(objectKeypoints.at(i).pt);
				indexes_1.push_back(i);

				mpts_2.push_back(sceneKeypoints.at(results.at<int>(i,0)).pt);
				indexes_2.push_back(results.at<int>(i,0));
			}
		}

		if(method == mInliers)
		{
			// FIND HOMOGRAPHY
			unsigned int minInliers = 8;
			if(mpts_1.size() >= minInliers)
			{
				cv::Mat H = findHomography(mpts_1,
						mpts_2,
						cv::RANSAC,
						1.0,
						outlier_mask);
				int inliers=0, outliers=0;
				for(unsigned int k=0; k<mpts_1.size();++k)
				{
					if(outlier_mask.at(k))
					{
						++inliers;
					}
					else
					{
						++outliers;
					}
				}
				if(!quiet)
					printf("Total=%d Inliers=%d Outliers=%d\n", (int)mpts_1.size(), inliers, outliers);
				value = (inliers*100) / (inliers+outliers);
			}
		}
		else
		{
			value = mpts_1.size();
		}
	}
	else
	{
		printf("Images are not valid!\n");
		showUsage();
	}
	if(!quiet)
		printf("Similarity = %d\n", value);
	return value;
}