我愿意从扭曲的图像中得到一个普通的矩形。
例如,一旦我有了这种图像:
...我想裁剪对应于以下矩形的区域:
...但是我的代码正在提取更大的框架:
我的代码如下所示:
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/