我愿意从扭曲的图像中得到一个普通的矩形。

例如,一旦我有了这种图像:

...我想裁剪对应于以下矩形的区域:

...但是我的代码正在提取更大的框架:

我的代码如下所示:

int main(int argc, char** argv) {
    cv::Mat img = cv::imread(argv[1]);

    // Convert RGB Mat to GRAY
    cv::Mat gray;
    cv::cvtColor(img, gray, CV_BGR2GRAY);

    // Store the set of points in the image before assembling the bounding box
    std::vector<cv::Point> points;
    cv::Mat_<uchar>::iterator it = gray.begin<uchar>();
    cv::Mat_<uchar>::iterator end = gray.end<uchar>();
    for (; it != end; ++it) {
        if (*it)
            points.push_back(it.pos());
    }

    // Compute minimal bounding box
    Rect box = cv::boundingRect(cv::Mat(points));

    // Draw bounding box in the original image (debug purposes)
    cv::Point2f vertices[4];
    vertices[0] = Point2f(box.x, box.y  +box.height);
    vertices[1] = Point2f(box.x, box.y);
    vertices[2] = Point2f(box.x+ box.width, box.y);
    vertices[3] = Point2f(box.x+ box.width, box.y   +box.height);

    for (int i = 0; i < 4; ++i) {
        cv::line(img, vertices[i], vertices[(i + 1) % 4], cv::Scalar(0, 255, 0), 1, CV_AA);
        cout << "==== vertices (x, y) = " << vertices[i].x << ", " << vertices[i].y << endl;
    }

    cv::imshow("box", img);
    cv::imwrite("box.png", img);

    waitKey(0);

    return 0;
}

关于如何找到菱形角并将其缩小为较小矩形的任何想法?

最佳答案

这个问题最困难的部分实际上是找到菱形角的位置。如果您实际使用的图像与示例中的图像有很大不同,则用于查找菱形角的特定过程可能不起作用。完成此操作后,您可以按角点到图像中心的距离对其进行排序。您正在寻找最靠近图像中心的点。

首先,必须为排序比较定义一个函子(如果可以使用C++ 11,则可能是lambda):

struct CenterDistance
{
    CenterDistance(cv::Point2f pt) : center(pt){}

    template <typename T> bool operator() (cv::Point_<T> p1, cv::Point_<T> p2) const
    {
        return cv::norm(p1-center) < cv::norm(p2-center);
    }

    cv::Point2f center;
};

实际上,这不一定是模板化的operator(),但它适用于任何cv::Point_类型。

对于示例图像,图像角点定义非常清晰,因此可以使用FAST之类的角点检测器。然后,您可以使用cv::convexHull()来获取外部点,该外部点应仅为菱形角。
int main(int argc, char** argv) {
    cv::Mat img = cv::imread(argv[1]);

    // Convert RGB Mat to GRAY
    cv::Mat gray;
    cv::cvtColor(img, gray, CV_BGR2GRAY);

    // Detect image corners
    std::vector<cv::KeyPoint> kpts;
    cv::FAST(gray, kpts, 50);

    std::vector<cv::Point2f> points;
    cv::KeyPoint::convert(kpts, points);
    cv::convexHull(points, points);

    cv::Point2f center(img.size().width / 2.f, img.size().height / 2.f);
    CenterDistance centerDistance(center);
    std::sort(points.begin(), points.end(), centerDistance);

    //The two points with minimum distance are what we want
    cv::rectangle(img, points[0], points[1], cv::Scalar(0,255,0));

    cv::imshow("box", img);
    cv::imwrite("box.png", img);

    cv::waitKey(0);

    return 0;
}

请注意,您可以使用cv::rectangle()代替从线条构造绘制的矩形。结果是:

关于c++ - 如何在OpenCV中找到菱形角并从中裁剪出一个较小的矩形?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17581268/

10-12 23:50