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

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

我问了一个类似的问题 操作。

之后, Mat 查找角落像素是微不足道的,我在回答。

#include< cv.h> #include< highgui.h> int main(int argc,char * argv []) { cv :: Mat img = cv :: imread(argv [1]); std :: cout<< 原始图像大小:<< img.size()<<的std :: ENDL; //将RGB Mat转换为GRAY cv :: Mat grey; cv :: cvtColor(img,grey,CV_BGR2GRAY); std :: cout<< 灰色图像大小:<< gray.size()<<的std :: ENDL; //侵蚀图像以消除不必要的噪音 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(灰色,灰色,元素); //扫描图像搜索点并将它们存储在向量中 std :: vector< cv :: Point>点; 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()); } //从积分中算出ROI的大小 int left,right,top,bottom; for(int i = 0; i< points.size(); i ++) { if(i == 0)//初始化角点值 { 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)); //为ROI计算最小边界框 //注意:由于某些未知原因,框的宽度/高度会被切换。 cv :: RotatedRect box = cv :: minAreaRect(cv :: Mat(box_points)); std :: cout<< box w:<< box.size.width<< h:<< box.size.height<<的std :: ENDL; //在原始图像中绘制边界框(调试目的) // 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); //将ROI设置为框$ $ $ b //所定义的区域注意:因为框的宽度/高度被切换, //它们是手动切换的代码如下: 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; //将原始图像裁剪为定义的ROI cv :: Mat crop = img(roi); //显示裁剪的投资回报率 cv :: imshow(裁剪投资回报率,作物); cv :: waitKey(0); 返回0; }

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

发布评论

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

>www.elefans.com

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