我在操作.
在那之后,在 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; iI 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 裁剪图像
发布评论