Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

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( indices.at<int>(0,j)).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);
    }
}

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( indices.at<int>(0,j)).position;
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);
    }
}