ok I figured it out this code should work when plugged with a qstringlist of files
QStringList videos;
Mat indexTemp;
struct frm
{
QString file;
int position;
cv::Mat descriptors;
};
QList<frm> frames;
foreach (video, videos)
{
process(video);
}
for (i = 0; i < indexTemp.rows; i++)
{
Mat mat = indexTemp.row(i);
Mat indices;
Mat dists;
int k = 3;
if (!mat.isContinuous() || mat.empty())
return;
try
{
mat = mat.reshape(1,1);
index.knnSearch(mat,indices,dists,k);
}
catch (Exception e)
{
qWarning() << "index search failure" << e.err.c_str() << e.msg.c_str();
}
catch (exception& e)
{
qWarning() << "index search failure" << e.what();
}
for (int j = 0; j < indices.cols; j++)
{
if (indices.at<int>(0,i) == -1 || dists.at<int>(0,j) < 12800) //knnsearch returns -1 for all cols after the matches it was able to find. 12800 is about 90% match with 500 ORB descriptors
continue;
try
{
QTime matchtime(0,0,0,0);
int matchms = frames.at(i).position;
matchtime = matchtime.addMSecs(matchms);
int temp = dists.at<int>(0,j);
qDebug() << frames.at(i).file << "frame"<< timestamp.toString("hh:mm:ss") << "match at"<< frames.at(indices.at<int>(0,j)).file << matchtime.toString("hh:mm:ss") << "distance" << temp;
}
catch (Exception e)
{
qWarning() << "failure in indices" << e.err.c_str() << e.msg.c_str() << e.func.c_str();
}
catch (exception &e)
{
qWarning() << "failure in indices" << e.what();
}
}
}
index.build(indexTemp,cv::flann::LshIndexParams(12,20,3), cvflann::FLANN_DIST_HAMMING);
void process(Qstring video)
{
if (video.isEmpty())
return;
int interval = 500;
int current_interval = 0;
UMat frame;
vector< cv::KeyPoint > keypoints;
Ptr<DescriptorExtractor> odetector = cv::ORB::create(500);
UMat imgDescriptor;
VideoCapture videocap(video.toStdString());
if (!videocap.isOpened())
{
failedstream << video << " could not be opened. Check permissions" << endl;
return;
}
for(; ; )
{
if (current_interval != 0)
videocap.set(CV_CAP_PROP_POS_MSEC,current_interval);
if (current_interval > videocap.get(CV_CAP_PROP_POS_MSEC) + 400) // I found some videos needed this in case the last from is not quite 500 ms away from the previous one
break;
if (!videocap.read(frame))
break;
current_interval += interval;
if (frame.empty() || !frame.isContinuous()) //skipping bad frames
continue;
odetector->detect(frame,keypoints);
odetector->compute(frame,keypoints,imgDescriptor);
if (imgDescriptor.empty() || !imgDescriptor.isContinuous()) // don't ask me how but even with all the frame checking this is still needed
{
qDebug() << "descriptors empty or corrupted" << imgDescriptor.empty() << imgDescriptor.isContinuous();
continue;
}
{
Mat imgDescriptorMat = imgDescriptor.getMat(cv::ACCESS_RW);
Mat matonerow;
frm tmp;
tmp.file = video;
tmp.position = current_interval;
if (imgDescriptorMat.rows < 500)
imgDescriptorMat.push_back(Mat::zeros((500 - imgDescriptorMat.rows),32,CV_8U));
matonerow = imgDescriptorMat.reshape(1,1);
indexTemp.push_back(matonerow);
imgDescriptorMat.copyTo(tmp.descriptors);
frames.append(tmp);
}
}
Look at these links to see how to use FLANN with binary descriptors:
those help, but what I really need now is some documentation on how to build the index with more than one image. I know it takes descriptors in the arguments, but can this be an array of arrays so each images descriptors are separate enough to tell which files match?