我是OpenCV的新手,如果无法正确表达问题,我深表歉意。

因此,我有一张转换为黑白的图像。现在,我要将白色像素的所有大块(块可以是任何形状)转换为黑色,并保留小的白色像素。

要进一步说明,请看下面的图片:
This pic

这是从另一个stackoverflow帖子中获得的,但是基本上我想做的就是摆脱那个白框,只在图片中添加文字。在这张照片中,我可以在顶部放一个黑框,因为我知道那个白框在哪里,但是当我不知道那个白框在哪里时该怎么办?

提前致谢

编辑:我想要的图片示例是here

最佳答案

您可以使用minArearect函数。此功能为每个轮廓绘制合适的矩形。您可以通过设置这些矩形边缘长度进行过滤。

        #include "opencv2/highgui/highgui.hpp"
        #include "opencv2/imgproc/imgproc.hpp"
        #include <iostream>
        #include <stdio.h>
        #include <stdlib.h>

        using namespace cv;
        using namespace std;


        int main()
        {

            Mat src; Mat src_gray;
            int thresh = 100;
            RNG rng(12345);
            /// Load source image and convert it to gray
            src = imread( "/ur/src/image_directory/image.png", 1 );
            Mat original = src.clone();
            /// Convert image to gray and blur it
            cvtColor( src, src_gray, CV_BGR2GRAY );
            blur( src_gray, src_gray, Size(3,3) );

            /// Create Window
            char* source_window = "Source";
            namedWindow( source_window, CV_WINDOW_AUTOSIZE );

            Mat threshold_output;
            vector<vector<Point> > contours;
            vector<Vec4i> hierarchy;

            /// Detect edges using Threshold
            threshold( src_gray, threshold_output, thresh, 255, THRESH_BINARY );
            /// Find contours
            findContours( threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );

            /// Find the rotated rectangles for each contour
            vector<RotatedRect> minRect( contours.size() );

            for( int i = 0; i < contours.size(); i++ )
                minRect[i] = minAreaRect( Mat(contours[i]) );


            int x1,x2,y1,y2;

            /// Draw contours + rotated rects
            Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 );
            Mat result_zero = Mat::zeros( threshold_output.size(), CV_8UC3 );

            for( int i = 0; i< contours.size(); i++ )
            {
                Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
                // contour
                drawContours( drawing, contours, i, color, 1, 8, vector<Vec4i>(), 0, Point() );
                // rotated rectangle
                Point2f rect_points[4]; minRect[i].points( rect_points );

                double length_1 = cv::norm(cv::Mat(rect_points[0]),cv::Mat(rect_points[1]));
                double length_2 = cv::norm(cv::Mat(rect_points[1]),cv::Mat(rect_points[2]));

                //This if scope for your desired rectangle size.You can set your size according to your rectangle(if it changes)
                if(length_1>30 && length_1<100 && length_2>30 && length_2<100)
                {
                    int min_x1 = INT_MAX, max_x2 = 0, min_y1 = INT_MAX, max_y2 = 0;

                    for( int j = 0; j < 4; j++ )
                    {
                        if(rect_points[j].x>max_x2 && rect_points[j].y>max_y2)
                        {
                            max_x2 = rect_points[j].x;
                            max_y2 = rect_points[j].y;
                        }

                        if(rect_points[j].x<min_x1 && rect_points[j].y<min_y1)
                        {
                            min_x1 = rect_points[j].x;
                            min_y1 = rect_points[j].y;

                        }

                        line( result_zero, rect_points[j], rect_points[(j+1)%4], color, 1, 8 );
                    }
                    x1 = min_x1;
                    x2 = max_x2;
                    y1 = min_y1;
                    y2 = max_y2;
                }
            }

            circle(result_zero,Point(x1,y1),3,Scalar(0,255,255),2);
            circle(result_zero,Point(x2,y2),3,Scalar(0,255,255),2);

            // Here in source image we make the rectangle black according to found points
            for(int i=y1-2;i<y2+2;i++)
            {
                for(int j=x1-2;j<x2+2;j++)
                {
                        src.at<cv::Vec3b>(i,j)[0]=0;
                        src.at<cv::Vec3b>(i,j)[1]=0;
                        src.at<cv::Vec3b>(i,j)[2]=0;
                }
            }

            /// Show in windows
            namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
            imshow("First",original);
            imshow( source_window, result_zero );
            imshow("Last",src);
            imshow( "Contours", drawing );
            waitKey(0);
            return(0);
        }

源图像:

c&#43;&#43; - OpenCV C&#43;&#43;:将白色像素的大块转换为黑色-LMLPHP

要点:

c&#43;&#43; - OpenCV C&#43;&#43;:将白色像素的大块转换为黑色-LMLPHP

结果:

c&#43;&#43; - OpenCV C&#43;&#43;:将白色像素的大块转换为黑色-LMLPHP

08-16 00:30