Пример #1
0
const std::vector<unsigned char> &chilitags::ReadBits::operator()(const cv::Mat &inputImage, const Quad &corners)
{
    cv::Mat_<cv::Point2f> cornersCopy(corners);

    auto roi = cv::boundingRect(cornersCopy);

    // Refine can actually provide corners outside the image
    roi.x = cv::max(roi.x, 0);
    roi.y = cv::max(roi.y, 0);
    roi.width = cv::min(roi.width, inputImage.cols-roi.x);
    roi.height = cv::min(roi.height, inputImage.rows-roi.y);

    cv::Point2f origin = roi.tl();
    for (int i : {0,1,2,3}) cornersCopy(i) -= origin;

    cv::Matx33f transformation = cv::getPerspectiveTransform(NORMALIZED_CORNERS, cornersCopy);

    cv::perspectiveTransform(mSamplePoints, mTransformedSamplePoints, transformation);

    cv::Mat inputRoi = inputImage(roi);

    uchar* sampleData = mSamples.ptr(0);
    for (auto& transformedSamplePoint : mTransformedSamplePoints) {
        *sampleData++ = inputRoi.at<uchar>(transformedSamplePoint);
    }

    cv::threshold(mSamples, mBits, -1, 1, cv::THRESH_BINARY | cv::THRESH_OTSU);

#ifdef DEBUG_ReadBits

    for (int i = 0; i < DATA_SIZE; ++i)
    {
        for (int j = 0; j < DATA_SIZE; ++j)
        {
            std::cout << (int) mBits[i*DATA_SIZE + j];
        }
        std::cout << "\n";
    }
    std::cout << std::endl;
#define ZOOM_FACTOR 10

    cv::Mat debugImage = inputImage.clone();

    cv::Mat tag;
    cv::resize(inputRoi, tag, cv::Size(0,0), ZOOM_FACTOR, ZOOM_FACTOR, cv::INTER_NEAREST);
    cv::cvtColor(tag, tag, cv::COLOR_GRAY2BGR);

    for (int i = 0; i < DATA_SIZE; ++i)
    {
        for (int j = 0; j < DATA_SIZE; ++j)
        {
            cv::Point2f position = mTransformedSamplePoints[i*DATA_SIZE + j];
            cv::circle(tag, position * ZOOM_FACTOR, 1,
                       cv::Scalar(0,255,0),2);
            cv::circle(tag, position * ZOOM_FACTOR, 3,
                       cv::Scalar::all(mBits[i*DATA_SIZE + j]*255),2);
        }
    }

    cv::circle(tag, *cornersCopy[0] * ZOOM_FACTOR, 3, cv::Scalar(255,0,0),2);

    cv::line(tag, *cornersCopy[0]*ZOOM_FACTOR, *cornersCopy[1]*ZOOM_FACTOR,cv::Scalar(255,0,0));
    cv::line(tag, *cornersCopy[1]*ZOOM_FACTOR, *cornersCopy[2]*ZOOM_FACTOR,cv::Scalar(255,0,255));
    cv::line(tag, *cornersCopy[2]*ZOOM_FACTOR, *cornersCopy[3]*ZOOM_FACTOR,cv::Scalar(255,0,255));
    cv::line(tag, *cornersCopy[3]*ZOOM_FACTOR, *cornersCopy[0]*ZOOM_FACTOR,cv::Scalar(255,0,255));

    cv::line(tag, *cornersCopy[2]*ZOOM_FACTOR, *cornersCopy[0]*ZOOM_FACTOR,cv::Scalar(255,0,255));
    cv::line(tag, *cornersCopy[3]*ZOOM_FACTOR, *cornersCopy[1]*ZOOM_FACTOR,cv::Scalar(255,0,255));

    cv::line(debugImage, *cornersCopy[0]+origin, *cornersCopy[1]+origin,cv::Scalar(255,0,255));
    cv::line(debugImage, *cornersCopy[1]+origin, *cornersCopy[2]+origin,cv::Scalar(255,0,255));
    cv::line(debugImage, *cornersCopy[2]+origin, *cornersCopy[3]+origin,cv::Scalar(255,0,255));
    cv::line(debugImage, *cornersCopy[3]+origin, *cornersCopy[0]+origin,cv::Scalar(255,0,255));


    cv::imshow("ReadBits-full", debugImage);
    cv::imshow("ReadBits-tag", tag);
    cv::waitKey(0);
#endif

    return mBits;
}
Пример #2
0
const std::vector<unsigned char>& ReadBits::operator()(const cv::Mat &inputImage, const Quad &corners)
{
    static const float TAG_SIZE = 2*TAG_MARGIN+DATA_SIZE;
    static const Quad NORMALIZED_CORNERS = {
         0.f,      0.f,
    TAG_SIZE,      0.f,
    TAG_SIZE, TAG_SIZE,
         0.f, TAG_SIZE
    };

    cv::Mat_<cv::Point2f> cornersCopy(corners);

    // Sometimes, the corners are refined into a concave quadrilateral
    // which makes ReadBits crash
    cv::Mat convexHull;
    cv::convexHull(cornersCopy, convexHull, true);
    if (convexHull.rows != 4) {
        cornersCopy = convexHull;
        cornersCopy.push_back(0.5f*(cornersCopy(0)+cornersCopy(1)));
    }

    auto roi = cv::boundingRect(cornersCopy);

    // Refine can actually provide corners outside the image
    roi.x = cv::max(roi.x, 0);
    roi.y = cv::max(roi.y, 0);
    roi.width = cv::min(roi.width, inputImage.cols-roi.x);
    roi.height = cv::min(roi.height, inputImage.rows-roi.y);

    cv::Point2f origin = roi.tl();
    for (int i : {0,1,2,3}) cornersCopy(i) -= origin;

    cv::Matx33f transformation = cv::getPerspectiveTransform(NORMALIZED_CORNERS, cornersCopy);

    cv::perspectiveTransform(mSamplePoints, mTransformedSamplePoints, transformation);

    cv::Mat inputRoi = inputImage(roi);

    uchar* sampleData = mSamples.ptr(0);
    for (auto& transformedSamplePoint : mTransformedSamplePoints) {
        transformedSamplePoint.x = cv::max(cv::min(roi.width - 1, (int)std::round(transformedSamplePoint.x)), 0);
        transformedSamplePoint.y = cv::max(cv::min(roi.height - 1, (int)std::round(transformedSamplePoint.y)), 0);

        *sampleData++ = inputRoi.at<uchar>(transformedSamplePoint);
    }

    cv::threshold(mSamples, mBits, -1, 1, cv::THRESH_BINARY | cv::THRESH_OTSU);

#ifdef DEBUG_ReadBits

    for (int i = 0; i < DATA_SIZE; ++i)
    {
        for (int j = 0; j < DATA_SIZE; ++j)
        {
            std::cout << (int) mBits[i*DATA_SIZE + j];
        }
        std::cout << "\n";
    }
    std::cout << std::endl;
#define ZOOM_FACTOR 10

    cv::Mat debugImage = inputImage.clone();

    cv::Mat tag;
    cv::resize(inputRoi, tag, cv::Size(0,0), ZOOM_FACTOR, ZOOM_FACTOR, cv::INTER_NEAREST);
    cv::cvtColor(tag, tag, cv::COLOR_GRAY2BGR);

    for (int i = 0; i < DATA_SIZE; ++i)
    {
        for (int j = 0; j < DATA_SIZE; ++j)
        {
            cv::Point2f position = mTransformedSamplePoints[i*DATA_SIZE + j];
            cv::circle(tag, position * ZOOM_FACTOR, 1,
                       cv::Scalar(0,255,0),2);
            cv::circle(tag, position * ZOOM_FACTOR, 3,
                       cv::Scalar::all(mBits[i*DATA_SIZE + j]*255),2);
        }
    }

    cv::circle(tag, *cornersCopy[0] * ZOOM_FACTOR, 3, cv::Scalar(255,0,0),2);

    cv::line(tag, *cornersCopy[0]*ZOOM_FACTOR, *cornersCopy[1]*ZOOM_FACTOR,cv::Scalar(255,0,0));
    cv::line(tag, *cornersCopy[1]*ZOOM_FACTOR, *cornersCopy[2]*ZOOM_FACTOR,cv::Scalar(255,0,255));
    cv::line(tag, *cornersCopy[2]*ZOOM_FACTOR, *cornersCopy[3]*ZOOM_FACTOR,cv::Scalar(255,0,255));
    cv::line(tag, *cornersCopy[3]*ZOOM_FACTOR, *cornersCopy[0]*ZOOM_FACTOR,cv::Scalar(255,0,255));

    cv::line(tag, *cornersCopy[2]*ZOOM_FACTOR, *cornersCopy[0]*ZOOM_FACTOR,cv::Scalar(255,0,255));
    cv::line(tag, *cornersCopy[3]*ZOOM_FACTOR, *cornersCopy[1]*ZOOM_FACTOR,cv::Scalar(255,0,255));

    cv::line(debugImage, *cornersCopy[0]+origin, *cornersCopy[1]+origin,cv::Scalar(255,0,255));
    cv::line(debugImage, *cornersCopy[1]+origin, *cornersCopy[2]+origin,cv::Scalar(255,0,255));
    cv::line(debugImage, *cornersCopy[2]+origin, *cornersCopy[3]+origin,cv::Scalar(255,0,255));
    cv::line(debugImage, *cornersCopy[3]+origin, *cornersCopy[0]+origin,cv::Scalar(255,0,255));


    cv::imshow("ReadBits-full", debugImage);
    cv::imshow("ReadBits-tag", tag);
    cv::waitKey(0);
#endif

    return mBits;
}