OpenCv 2.3 C – 如何隔离图像内的对象
我有一个像这样的图像:
我想删除数字周围的黑色行和列。 所以我想要的结果是:
我试试这个:
void findX(IplImage* imgSrc,int* min, int* max){ int i; int minFound=0; CvMat data; CvScalar maxVal=cvRealScalar(imgSrc->width * 255); CvScalar val=cvRealScalar(0); //For each col sum, if sum < width*255 then we find the min //then continue to end to search the max, if sum< width*255 then is new max for (i=0; iwidth; i++){ cvGetCol(imgSrc, &data, i); val= cvSum(&data); if(val.val[0] width * 255); CvScalar val=cvRealScalar(0); //For each col sum, if sum < width*255 then we find the min //then continue to end to search the max, if sum< width*255 then is new max for (i=0; iheight; i++){ cvGetRow(imgSrc, &data, i); val= cvSum(&data); if(val.val[0] < maxVal.val[0]){ *max=i; if(!minFound){ *min= i; minFound= 1; } } } } CvRect findBB(IplImage* imgSrc){ CvRect aux; int xmin, xmax, ymin, ymax; xmin=xmax=ymin=ymax=0; findX(imgSrc, &xmin, &xmax); findY(imgSrc, &ymin, &ymax); aux=cvRect(xmin, ymin, xmax-xmin, ymax-ymin); //printf("BB: %d,%d - %d,%d\n", aux.x, aux.y, aux.width, aux.height); return aux; }
所以我使用:
IplImage *my_image = cvLoad.... CvRect bb = findBB(my_image); IplImage *new_image = cvCreateImage(cvSize(bb.width,bb.height), my_image->depth, 1); cvShowImage("test",new_image);
它不能正常工作,因为我试图检查新图像中是否有黑色行或列并且它们存在。 我能做什么? 有人能帮我吗? (对不起我的英语不好!)
一种方法是简单地执行边界框技术来检测数字,如下图所示:
由于您的图像已经处理,我使用的边界框技术要简单得多。
在该过程之后,您真正需要做的就是将原始图像的ROI(感兴趣区域)设置为框所定义的区域,以实现裁剪效果并隔离对象:
请注意,在生成的图像中,边框中有一个额外的行/列像素不是白色。 嗯,他们也不是黑人。 那是因为我没有执行任何阈值方法将图像二值化为黑白。 下面的代码演示了在图像的灰度版本上执行的边界框技术。
这几乎是实现您想要的路线图。 出于教育目的,我正在使用OpenCV的C ++接口共享我编写的代码。 我相信你有能力将它转换为C接口。
#include #include #include 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 points; cv::Mat_::iterator it = gray.begin (); cv::Mat_ ::iterator end = gray.end (); for (; it != end; ++it) { if (*it) points.push_back(it.pos()); } // Compute minimal bounding box cv::RotatedRect box = cv::minAreaRect(cv::Mat(points)); // Draw bounding box in the original image (debug 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("box", img); //cv::imwrite("box.png", img); // Set Region of Interest to the area defined by the box cv::Rect roi; roi.x = box.center.x - (box.size.width / 2); roi.y = box.center.y - (box.size.height / 2); roi.width = box.size.width; roi.height = box.size.height; // Crop the original image to the defined ROI cv::Mat crop = img(roi); cv::imshow("crop", crop); cv::imwrite("cropped.png", crop); cvWaitKey(0); return 0; }