如何确定感兴趣的区域,然后使用 OpenCV 裁剪图像

编程入门 行业动态 更新时间:2024-10-26 16:21:52
本文介绍了如何确定感兴趣的区域,然后使用 OpenCV 裁剪图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我在操作.

在那之后,在 Mat 上进行简单的迭代来寻找角落像素 是微不足道的,我在 回答.

#include #include int main(int argc, char* argv[]){cv::Mat img = cv::imread(argv[1]);std::cout <<原始图像尺寸:" <积分;cv::Mat_::iterator it = gray.begin();cv::Mat_::iterator end = gray.end();for (; it != end; it++){如果它)points.push_back(it.pos());}//从这些点,算出ROI的大小int 左、右、上、下;for (int i = 0; i 底部)底部 = 点 [i].y;}std::vectorbox_points;box_points.push_back(cv::Point(left, top));box_points.push_back(cv::Point(left, bottom));box_points.push_back(cv::Point(right, bottom));box_points.push_back(cv::Point(right, top));//计算 ROI 的最小边界框//注意:由于某些未知原因,框的宽度/高度发生了切换.cv::RotatedRect box = cv::minAreaRect(cv::Mat(box_points));std::cout <<框 w:"<<box.size.width <<" h:" <<box.size.height <<std::endl;//在原始图像中绘制边界框(调试目的)//cv::Point2f 顶点[4];//box.points(vertices);//for (int i = 0; i <4; ++i)//{//cv::line(img, vertices[i], vertices[(i + 1) % 4], cv::Scalar(0, 255, 0), 1, CV_AA);//}//cv::imshow("原始", img);//cv::waitKey(0);//将ROI设置为框定义的区域//注意:因为盒子的宽/高是切换的,//它们是在下面的代码中手动切换的:简历::矩形投资回报率;roi.x = box.center.x - (box.size.height/2);roi.y = box.center.y - (box.size.width/2);roi.width = box.size.height;roi.height = box.size.width;std::cout <<"roi @" <<roi.x<<,"<<roi.y<<" " <<roi.width<

I asked a similar question here but that is focused more on tesseract.

I have a sample image as below. I would like to make the white square my Region of Interest and then crop out that part (square) and create a new image with it. I will be working with different images so the square won't always be at the same location in all images. So I will need to somehow detect the edges of the square.

What are some pre-processing methods I can perform to achieve the result?

解决方案

Using your test image I was able to remove all the noises with a simple erosion operation.

After that, a simple iteration on the Mat to find for the corner pixels is trivial, and I talked about that on this answer. For testing purposes we can draw green lines between those points to display the area we are interested at in the original image:

At the end, I set the ROI in the original image and crop out that part.

The final result is displayed on the image below:

I wrote a sample code that performs this task using the C++ interface of OpenCV. I'm confident in your skills to translate this code to Python. If you can't do it, forget the code and stick with the roadmap I shared on this answer.

#include <cv.h> #include <highgui.h> int main(int argc, char* argv[]) { cv::Mat img = cv::imread(argv[1]); std::cout << "Original image size: " << img.size() << std::endl; // Convert RGB Mat to GRAY cv::Mat gray; cv::cvtColor(img, gray, CV_BGR2GRAY); std::cout << "Gray image size: " << gray.size() << std::endl; // Erode image to remove unwanted noises int erosion_size = 5; cv::Mat element = cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(2 * erosion_size + 1, 2 * erosion_size + 1), cv::Point(erosion_size, erosion_size) ); cv::erode(gray, gray, element); // Scan the image searching for points and store them in a vector 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()); } // From the points, figure out the size of the ROI int left, right, top, bottom; for (int i = 0; i < points.size(); i++) { if (i == 0) // initialize corner values { left = right = points[i].x; top = bottom = points[i].y; } if (points[i].x < left) left = points[i].x; if (points[i].x > right) right = points[i].x; if (points[i].y < top) top = points[i].y; if (points[i].y > bottom) bottom = points[i].y; } std::vector<cv::Point> box_points; box_points.push_back(cv::Point(left, top)); box_points.push_back(cv::Point(left, bottom)); box_points.push_back(cv::Point(right, bottom)); box_points.push_back(cv::Point(right, top)); // Compute minimal bounding box for the ROI // Note: for some unknown reason, width/height of the box are switched. cv::RotatedRect box = cv::minAreaRect(cv::Mat(box_points)); std::cout << "box w:" << box.size.width << " h:" << box.size.height << std::endl; // Draw bounding box in the original image (debugging purposes) //cv::Point2f vertices[4]; //box.points(vertices); //for (int i = 0; i < 4; ++i) //{ // cv::line(img, vertices[i], vertices[(i + 1) % 4], cv::Scalar(0, 255, 0), 1, CV_AA); //} //cv::imshow("Original", img); //cv::waitKey(0); // Set the ROI to the area defined by the box // Note: because the width/height of the box are switched, // they were switched manually in the code below: cv::Rect roi; roi.x = box.center.x - (box.size.height / 2); roi.y = box.center.y - (box.size.width / 2); roi.width = box.size.height; roi.height = box.size.width; std::cout << "roi @ " << roi.x << "," << roi.y << " " << roi.width << "x" << roi.height << std::endl; // Crop the original image to the defined ROI cv::Mat crop = img(roi); // Display cropped ROI cv::imshow("Cropped ROI", crop); cv::waitKey(0); return 0; }

更多推荐

如何确定感兴趣的区域,然后使用 OpenCV 裁剪图像

本文发布于:2023-05-26 09:48:13,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/252260.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:感兴趣   图像   区域   OpenCV

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!