问题描述
我在图像中有很多点,我想找到最接近给定点的点。
尝试过的现有方法: 将图像划分为图块,并仅通过构建表格在感兴趣区域内搜索。淡蓝色的是我正在比较的要点。
问题 即使进行的比较很少,我的算法所花费的时间也比实际时间多。我目前的方法是否还有改进的余地?还有其他更好的方法吗?
我的机器上的运行时间: 花费的时间
FindNearestPoint : 0.021145 ms
FindNearestPointV2: 0.047953 ms
PC配置: Intel(R)Core(TM)i7-6820HQ cpu @ 2.70 GHZ
// Feature Comparision.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
//
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <vector>
#include "Timer.h" //http://www.songho.ca/misc/timer/files/timer.zip
#include "opencv2\opencv.hpp"
#include "opencv2\opencv_modules.hpp"
using namespace cv;
using namespace std;
bool FindNearestPoint(const Point2f Point,const vector<Point2f>vPoints,int &Index )
{
CV_Assert(vPoints.size() != 0);
float Prevdistance = FLT_MAX;
Index = -1;//Error Case
for (size_t i = 0; i < vPoints.size(); i++)
{
float distance = cv::norm(Point - Point2f(vPoints[i].x,vPoints[i].y));
if (distance < Prevdistance)
{
Index = i;
Prevdistance = distance;
}
}
return true;
}
static inline bool GetlistofClustersToProcess(const Point2f Pt,const Point2f szTileSize,const Size GridSize,vector<Point> &ClusterIndices)
{
Point Index(Pt.x* szTileSize.x,Pt.y * szTileSize.y);
vector<Point> vClusterIndices;
//Prev Tile
vClusterIndices.push_back(Index + Point(-1,-1));//Prev Tile
vClusterIndices.push_back(Index + Point(-1,0)); //Curr Tile
vClusterIndices.push_back(Index + Point(-1,1)); //Next Tile
vClusterIndices.push_back(Index + Point(0,-1)); //Prev Tile
vClusterIndices.push_back(Index + Point(0,0)); //Curr Tile
vClusterIndices.push_back(Index + Point(0,1)); //Next Tile
vClusterIndices.push_back(Index + Point(1,-1)); //Prev Tile
vClusterIndices.push_back(Index + Point(1,0)); //Curr Tile
vClusterIndices.push_back(Index + Point(1,1)); //Next Tile
for (size_t i = 0; i < vClusterIndices.size(); i++)
{
Index = vClusterIndices[i];
if ((Index.x < 0) || (Index.x >= GridSize.width) || (Index.y < 0) || (Index.y >= GridSize.height))
{
continue;
}
ClusterIndices.push_back(Index);
}
return true;
}
bool FindNearestPointV2(const Point2f Point,const vector<vector<vector<int>>>vClusters,int &Index,Mat &mDebugImage)
{
#define EnableDebug 0
CV_Assert(vPoints.size() != 0);
vector<cv::Point> ClusterIndices;
ClusterIndices.clear();
GetlistofClustersToProcess(Point,szTileSize,GridSize,ClusterIndices);
float Prevdistance = FLT_MAX;
Index = -1;//Error Case
int KeypointIdx = 0;
for (size_t iClusterIdx = 0; iClusterIdx < ClusterIndices.size(); iClusterIdx++)
{
cv::Point Cluster(ClusterIndices[iClusterIdx]);
CV_Assert((Cluster.x >= 0)&&(Cluster.x < GridSize.width));
CV_Assert((Cluster.y >= 0) && (Cluster.y < GridSize.height));
for (size_t i = 0; i < vClusters[Cluster.y][Cluster.x].size(); i++)
{
KeypointIdx = vClusters[Cluster.y][Cluster.x][i];
CV_Assert(KeypointIdx < vPoints.size());
float distance = cv::norm(Point - Point2f(vPoints[KeypointIdx].x,vPoints[KeypointIdx].y));
#if EnableDebug
circle(mDebugImage,vPoints[KeypointIdx],2,Scalar(255,255,0),2);
imshow("Input Features",mDebugImage);
#endif
//New Optimized Implementation
//waitKey();
if (distance < Prevdistance)
{
Index = KeypointIdx;
Prevdistance = distance;
}
}
}
return true;
}
int main(int argc,char* argv[])
{
/*TestKNN();
return 0;*/
Size ImageSize(900,300);
Mat mInputimage(ImageSize,CV_8UC3,Scalar::all(0));
RNG rng(0xFFFFFFFF);
vector<Point2f>vKeypoints;
int MaxNoOfKeypoints = 2000;
uint16_t maxFilteredKeypoints = 350;
int TileSize = 32;//Tile Size in Pixels
Size GridSize((ImageSize.width / TileSize)+1,(ImageSize.height / TileSize)+1);
vector<vector<vector<int>>>vClusters;
Point ptTileIdx(0,0);
Point2f PtQuery,PtNearestPoint,PtNearestPointV2;
Point2f GridScale((float)GridSize.width / (float)ImageSize.width,(float)GridSize.height / (float)ImageSize.height);
int NoOfTestPoints = 100,Iteration = 0;
for (;;)
{
vKeypoints.clear();
vClusters.clear();
mInputimage.setTo(0);
//Generating Random Keypoints
for (size_t i = 0; i < MaxNoOfKeypoints; i++)
{
vKeypoints.push_back(Point2f(rng.uniform(0,ImageSize.width),rng.uniform(0,ImageSize.height)));
}
cout << "Grid Size :" << GridSize << "\n";
for (size_t iVerTile = 0; iVerTile < GridSize.height; iVerTile++)
{
vector<vector<int>>HorTiles;
Scalar color = Scalar(rng.uniform(0,255),255));
for (size_t iHorTile = 0; iHorTile < GridSize.width; iHorTile++)
{
Rect TileRect(iHorTile*TileSize,iVerTile*TileSize,TileSize,TileSize);
rectangle(mInputimage,TileRect,color,1);
color += Scalar(0,10);
HorTiles.push_back(vector<int>());
}
vClusters.push_back(HorTiles);
}
printf("Cluster Size : %d,%d \n",vClusters.size(),vClusters[0].size());
//Classify Tile Idx for all the Keypoints
for (size_t i = 0; i < MaxNoOfKeypoints; i++)
{
ptTileIdx.x = (int)(vKeypoints[i].x / TileSize);
ptTileIdx.y = (int)(vKeypoints[i].y / TileSize);
vClusters[ptTileIdx.y][ptTileIdx.x].push_back(i);
}
//displaying the Keypoints
for (size_t i = 0; i < MaxNoOfKeypoints; i++)
{
circle(mInputimage,vKeypoints[i],2);
}
Mat mInputTestimage = mInputimage.clone();
Iteration = 0;
while (Iteration<NoOfTestPoints)
{
PtQuery = Point2f(rng.uniform(0,ImageSize.height));
circle(mInputTestimage,PtQuery,4,Scalar(0,4);
circle(mInputTestimage,2);
int NearestPointIndex = -1,NearestPointIndexV2 = -1;
Timer t_FindNearestPt;
t_FindNearestPt.start();
FindNearestPoint(PtQuery,vKeypoints,NearestPointIndex);
t_FindNearestPt.stop();
PtNearestPoint = vKeypoints[NearestPointIndex];
Timer t_FindNearestPtV2;
t_FindNearestPtV2.start();
//New Optimized Implementation
FindNearestPointV2(PtQuery,vClusters,GridScale,NearestPointIndexV2,mInputTestimage);
t_FindNearestPtV2.stop();
PtNearestPointV2 = vKeypoints[NearestPointIndexV2];
if (NearestPointIndexV2 != -1)
{
circle(mInputTestimage,PtNearestPointV2,2);
}
if (NearestPointIndex != -1)
{
circle(mInputTestimage,2);
}
if (NearestPointIndex != NearestPointIndexV2)
{
printf("[Error] Closest Point not Matching! \n");
cout << "Point" << PtQuery << " Org" << PtNearestPoint << "!= V2 " << PtNearestPointV2 << "\n";
float distance = cv::norm(PtQuery - PtNearestPoint);
float distanceV2 = cv::norm(PtQuery - PtNearestPointV2);
printf("distance : %f - %f \n",distance,distanceV2);
}
/*else
{
printf("[Passed] Closest Point Matching! \n");
}*/
float TiMetaken_C = t_FindNearestPt.getelapsedtimeInMilliSec();
printf("Time Taken for FindNearestPoint : %f ms\t",TiMetaken_C);
printf("FindNearestPointV2: %f ms\t",t_FindNearestPtV2.getelapsedtimeInMilliSec());
printf("Speed: %f x\n",TiMetaken_C/t_FindNearestPtV2.getelapsedtimeInMilliSec());
imshow("Input Features",mInputTestimage);
Iteration++;
char key = (char)waitKey();
if (key == 27 || key == 'q' || key == 'Q') // 'ESC'
break;
mInputTestimage= mInputimage.clone();
}
char key = (char)waitKey();
if (key == 27 || key == 'q' || key == 'Q') // 'ESC'
break;
}
return 0;
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)