Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <cstdio>
#include <sstream>
#include <iterator>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <QDir>
#include "Helpers.hpp"
struct MyLessThan {
bool operator()(const QString &s1, const QString &s2) const {
QRegExp rx("[-]");// match a comma or a space
QStringList list1 = s1.split(rx, QString::SkipEmptyParts);
QStringList list2 = s2.split(rx, QString::SkipEmptyParts);
int it1 = list1[1].toInt();
int it2 = list2[1].toInt();
if (it1 < it2)
return true;
return false;
}
};
// This is an annotation tool that probably is not generic right now
// Use this is to define center of a fingertip and write this to a file
// This can later be used elsewhere for training ML algorithms
int main(int argc, char** argv)
{
if(argc < 3 || argc > 6)
{
std::cout << "[ USAGE ]: " << argv[0] << " <Path_to_Data> <Path_to_output_annotation_file> [<MaxAnnoSize = 8>] <path-to-intrinsics> <lexicographically sort names (specific format,optional)>" << std::endl;
getchar();
return -1;
}
std::ifstream intrFile(argv[4]);
// Do whatever
intrinsics.resize(4);
for (int i = 0; i < intrinsics.size(); i++) intrFile >> intrinsics[i];
intrFile.close();
// if(argc == 4 || argc ==5)
// {
g_MaxAnnoSize = atoi(argv[3]);
if(g_MaxAnnoSize != 3 && g_MaxAnnoSize != 5 && g_MaxAnnoSize != 8)
{
std::cout << "[ ERR ]: Only three posible values for MaxAnnoSize supported (3, 5, or 8). Provided " << g_MaxAnnoSize << ". Aborting." << std::endl;
getchar();
return -3;
}
// }
g_BaseDataDir = std::string(argv[1]);
// g_OutFile.open(std::string(argv[2]), std::fstream::in | std::fstream::out | std::fstream::trunc);
// g_OutFile3D.open(std::string(argv[2]) + "_3D.txt", std::fstream::in | std::fstream::out | std::fstream::trunc);
g_OutFile.open(std::string(argv[2]), std::fstream::in | std::fstream::out | std::fstream::app);
g_OutFile3D.open(std::string(argv[2]) + "_3D.txt", std::fstream::in | std::fstream::out | std::fstream::app);
if(g_OutFile.is_open() == false || g_OutFile3D.is_open() == false)
{
std::cout << "[ ERR ]: Unable to open output file. Aborting." << std::endl;
getchar();
return -2;
}
// {
// std::fstream OutFile(std::string(argv[2]) + ".bkp", std::fstream::in | std::fstream::out | std::fstream::trunc);
// std::fstream OutFile3D(std::string(argv[2]) + "_3D.txt.bkp", std::fstream::in | std::fstream::out | std::fstream::trunc);
// std::stringstream ss;
// std::copy(std::istreambuf_iterator<char>(OutFile),
// std::istreambuf_iterator<char>(),
// std::ostreambuf_iterator<char>(ss));
// OutFile << ss.str();
// ss.str(std::string());
// std::copy(std::istreambuf_iterator<char>(OutFile3D),
// std::istreambuf_iterator<char>(),
// std::ostreambuf_iterator<char>(ss));
// OutFile3D << ss.str();
// }
// Read existing annotations
int nLines = std::count(std::istreambuf_iterator<char>(g_OutFile),
std::istreambuf_iterator<char>(), '\n') - 1;
int nLines3D = std::count(std::istreambuf_iterator<char>(g_OutFile3D),
std::istreambuf_iterator<char>(), '\n') - 1;
g_OutFile.seekg(0);
g_OutFile3D.seekg(0);
std::cout << "------------------------------\nInstructions\n------------------------------\n";
std::cout << "The window on the left displays the currently loaded depth image. The right window shows the corresponding color image (with a progress bar at the bottom).\n";
std::cout << "The goal is to label fingertips+cuboid (8 points), only cuboid (3 points), or only fingertips (5 points).\n\n";
std::cout << "Left Mouse Click: Selects a point on the image and displays in red.\n";
std::cout << "Space Key: Adds currently selected point into annotation list turning the box into green.\n";
std::cout << "'n' / 'p' Keys: Move to next or previous frames.\n";
std::cout << "'c' Key: Clear annotation list for current frame.\n";
std::cout << "'v' Key: Copy and paste annotation list from previous frame.\n";
std::cout << "'w' Key: Write current annotation list to file and move to next frame.\n\n\n";
QDir BaseDirColor, BaseDir16U;
BaseDirColor = QDir(QString((g_BaseDataDir+"//color//").c_str()));
BaseDirColor.setNameFilters(QStringList() << "*.png" << "*.bmp");
BaseDir16U = QDir(QString((g_BaseDataDir + "//depth//").c_str()), "*.png");
g_ImageList = BaseDir16U.entryList();
g_ImageListColor = BaseDirColor.entryList();
g_FileCount = g_ImageList.size();
if (argc == 6){
MyLessThan le;
qSort(g_ImageList.begin(), g_ImageList.end(), le);
qSort(g_ImageListColor.begin(), g_ImageListColor.end(), le);
}
else{
qSort(g_ImageList.begin(), g_ImageList.end());
qSort(g_ImageListColor.begin(), g_ImageListColor.end());
}
//for (int i = 0; i < 10; i++)
// std::cout << g_ImageList.at(i).toUtf8().constData() << std::endl;
// Check if there are same number of 16U images
if(g_FileCount < 1 || g_ImageListColor.size() != g_FileCount)
{
std::cout << "[ ERR ]: Number of depth and color images don't match (" << g_FileCount << ") vs. (" << g_ImageListColor.size() << ")" << std::endl;
return -1;
}
else
std::cout << "[ INFO ]: Found " << g_FileCount << " files for annotation." << std::endl;
// Create some windows before proceeding
cv::namedWindow(g_MainWindTitle, CV_WINDOW_NORMAL);
cv::resizeWindow(g_MainWindTitle, 640, 480);
cv::moveWindow(g_MainWindTitle, 600, 50);
cv::namedWindow(g_ColorWindTitle, CV_WINDOW_NORMAL);
cv::resizeWindow(g_ColorWindTitle, 640, 480);
cv::moveWindow(g_ColorWindTitle, 600 + 650, 50);
cv::setMouseCallback(g_MainWindTitle, AnnotateImage, 0);
if(g_FileCount > 0)
{
g_CurrImage = cv::imread(g_BaseDataDir + "//depth//"+ QDir::separator().toAscii() + g_ImageList[g_CurrFileCtr].toUtf8().constData(), -1);
g_CurrColorImage = cv::imread(g_BaseDataDir+ "//color//" + QDir::separator().toAscii() + g_ImageListColor[g_CurrFileCtr].toUtf8().constData(), -1);
MakeDisplayImage(g_CurrImage, g_CurrDispImage);
g_ImageAnnoLists.resize(g_FileCount);
g_CurrImageAnnoList = &g_ImageAnnoLists[0];
if(nLines > 0 && nLines == nLines3D && nLines == g_FileCount)
ReadAnnotations();
else
{
// std::cout << "[ WARN ]: Passed annotation file does not match dataset or this is the first time this dataset is being annotated. Backed up the file (.bkp files) and writing new annotations." << std::endl;
std::cout << "[ WARN ]: Passed annotation file does not match dataset or this is the first time this dataset is being annotated. Will write new annotations." << std::endl;
std::cout << "nLines: " << nLines << std::endl;
}
}
g_OutFile.close();
g_OutFile3D.close();
while(true)
{
bool gotoNext = false;
char ch = cv::waitKey(1);
if(ch == 27)
break;
if(ch == 'w')
{
std::cout << "[ INFO ]: Writing image annotations thus far to file..." << std::endl;
g_OutFile.open(std::string(argv[2]), std::fstream::in | std::fstream::out | std::fstream::trunc);
g_OutFile3D.open(std::string(argv[2]) + "_3D.txt", std::fstream::in | std::fstream::out | std::fstream::trunc);
if(g_OutFile.is_open() == false || g_OutFile3D.is_open() == false)
{
std::cout << "[ ERR ]: Unable to open output file. Aborting." << std::endl;
return -2;
}
WriteAnnotations();
g_OutFile.close();
g_OutFile3D.close();
gotoNext = true;
}
if(ch == 'n' || gotoNext)
{
if(g_CurrFileCtr < g_FileCount-1)
{
g_CurrFileCtr++;
// std::cout << "[ INFO ]: Loading file for annotation: " << g_ImageList[g_CurrFileCtr].toUtf8().constData() << std::endl;
}
else
std::cout << "[ INFO ]: Reached end of file list." << std::endl;
}
if(ch == 'p')
{
if(g_CurrFileCtr > 0)
{
g_CurrFileCtr--;
// std::cout << "[ INFO ]: Loading file for annotation: " << g_ImageList[g_CurrFileCtr].toUtf8().constData() << std::endl;
}
else
std::cout << "[ INFO ]: Reached start of file list." << std::endl;
}
g_CurrImage = cv::imread(g_BaseDataDir+ "//depth//" + QDir::separator().toAscii() + g_ImageList[g_CurrFileCtr].toUtf8().constData(), -1);
g_CurrColorImage = cv::imread(g_BaseDataDir + "//color//"+QDir::separator().toAscii() + g_ImageListColor[g_CurrFileCtr].toUtf8().constData(), -1);
MakeDisplayImage(g_CurrImage, g_CurrDispImage);
g_CurrImageAnnoList = &g_ImageAnnoLists[g_CurrFileCtr];
if(ch == ' ')
{
if(g_CurrImageAnnoList != NULL)
{
int AnnoListSize = g_CurrImageAnnoList->m_AnnoList.size();
if(AnnoListSize == g_MaxAnnoSize)
{
std::cout << "[ WARN ]: Reached max capacity of annotations for this image (" << g_MaxAnnoSize << "). Not pushing." << std::endl;
}
else
{
if(AnnoListSize == 0)
{
g_CurrImageAnnoList->m_AnnoList.push_back(g_LastAnno);
// std::cout << "[ INFO ]: Pushed last clicked box into annotation list for current image." << std::endl;
}
else
{
if(g_CurrImageAnnoList->m_AnnoList[AnnoListSize - 1].m_X == g_LastAnno.m_X
&& g_CurrImageAnnoList->m_AnnoList[AnnoListSize - 1].m_Y == g_LastAnno.m_Y)
{
std::cout << "[ WARN ]: Annotation box is already in the list. Not pushing." << std::endl;
}
else
{
g_CurrImageAnnoList->m_AnnoList.push_back(g_LastAnno);
// std::cout << "[ INFO ]: Pushed last clicked box into annotation list for current image." << std::endl;
}
}
// std::cout << "[ INFO ]: Number of annotation boxes in current image: "
// << g_CurrImageAnnoList->m_AnnoList.size()
// << std::endl;
}
}
}
if(ch == 'c')
{
if(g_CurrImageAnnoList != NULL)
{
g_CurrImageAnnoList->m_AnnoList.clear();
g_CurrImageAnnoList->m_readDepthImage = true;
std::cout << "[ INFO ]: Cleared all current annotated boxes in current image." << std::endl;
}
}
if (ch == 'v')
{
if (g_CurrImageAnnoList != NULL)
g_CurrImageAnnoList->m_AnnoList.clear();
for (int i = 0; i < g_ImageAnnoLists[g_CurrFileCtr - 1].m_AnnoList.size(); i++)
{
g_CurrImageAnnoList->m_AnnoList.push_back(g_ImageAnnoLists[g_CurrFileCtr - 1].m_AnnoList[i]);
g_CurrImageAnnoList->m_readDepthImage = true;
}
std::cout << "[ INFO ]: Copied annotations from previous frame." << std::endl;
}
if(g_CurrDispImage.empty() == false)
{
// Draw current annotations to image
if(g_LastAnno.m_X > 0)
DrawBox(g_LastAnno);
if(g_CurrImageAnnoList != NULL)
{
for(int ACtr = 0; ACtr < g_CurrImageAnnoList->m_AnnoList.size(); ++ACtr)
{
if(g_CurrImageAnnoList->m_AnnoList[ACtr].m_X > 0)
DrawBox(g_CurrImageAnnoList->m_AnnoList[ACtr], cv::Scalar(0.0, 255.0, 0.0), ACtr+1);
}
}
cv::imshow(g_MainWindTitle, g_CurrDispImage);
cv::imshow(g_ColorWindTitle, g_CurrColorImage);
// std::stringstream ss;
// ss << "/home/ssridhar/Desktop/Dexter++/Images/" << std::setfill('0') << std::setw(6) << g_CurrFileCtr << ".png";
// cv::imwrite(ss.str(), g_CurrDispImage);
}
}
return 0;
}