提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
由之前的工作计划,使用摄像头采集数据并训练神经网络来预测物体的特征点,目前的想法是采用FCN或者UNET来构建特征点检测网络。而该步骤的第一部分为构建数据集。由于在网上未找到一键标注且生成热力图的工具由此决定自己来写一个这样的小程序。
开发环境:vs2019 ,OpenCV4.4
思路:采用C++的io处理库获取文件夹下的所有图片名称,之后使用OpenCV读取这些文件名对应的图片,使用OpenCV鼠标处理事件,通过回调函数来记录鼠标的坐标,并且生成热力图。并用C++文件流将坐标写入文件。
代码如下(示例):
#include
#include
#include
#include
#include
#include
#include
代码如下(示例):
void getFiles(std::string path,std::vector<std::string>& files)
{
_finddata_t fileInfo;
std::string p;
p.assign(path);
intptr_t handle = _findfirst((p+"//*.jpg").c_str(), &fileInfo);
do
{
std::string name = p + fileInfo.name;
//std::cout << name<< std::endl;
files.push_back(name);
} while (_findnext(handle, &fileInfo) == 0);
_findclose(handle);
}
_finddata_t这个结构体存储了文件名,通过_findfirst寻找文件。
void saveMat(cv::Mat &img1)
{
std::string folderPath = "存储路径";
std::string png = "jpg";
folderPath = folderPath + std::to_string(num);
folderPath.push_back('_');
folderPath = folderPath + std::to_string(n);
folderPath.push_back('.');
folderPath = folderPath + png;
cv::imwrite(folderPath, img1);
std::cout <<folderPath<< std::endl;
n++;
}
void writefile(int a, int b)
{
std::ofstream outfile;
outfile.open("存储路径", std::ios::out | std::ios::app);
outfile <<num<<" "<<n<<"("<<a<<","<<b<<")"<< std::endl;
outfile.close();
}
void MouseEvent(int event, int x, int y, int flags, void* data)
{
if (event == cv::EVENT_LBUTTONDOWN)
{
cv::Mat hm = img;
double x1 = x, y1 = y;
circle(img, cv::Point(x, y), 1, cv::Scalar(0, 0, 255));
cv::cvtColor(hm, hm, cv::COLOR_RGB2GRAY);
cv::Mat M(hm.rows, hm.cols, CV_64FC1, cv::Scalar(0, 0, 255));
for (auto i = 0; i < hm.rows; i++)/*生成热力图*/
{
for (auto j = 0; j < hm.cols; j++)
{
double a1 = i, b1 = j;
double u = (a1-x1)*(a1-x1)+(b1-y1)*(b1-y1);
u = -u / 2 / v / v;
double e = std::exp(u);
M.at<double>(i, j) = e*100;
/*std::cout << u << "******" << e;
return;*/
}
}
saveMat(M);
writefile(x, y);
}
}
std::vector<std::string>filename;
std::string imgpath = "图片路径";
getFiles(imgpath, filename);
for (auto i : filename)
{
std::cout << i << std::endl;
std::cout << num << std::endl;
img = cv::imread(i);
cv::resize(img, img, cv::Size(1008,756));
cv::namedWindow("img");
cv::imshow("img", img);
cv::setMouseCallback("img", MouseEvent);
while (1)
{ if (cv::waitKey(0) == 27)
break;
}
cv::destroyAllWindows();
num++;
n = 0;
}
以上代码可以实现一键关键点坐标保存和热力图生成,既是点击图片上的一点直接保存坐标和生成热力图。