简体   繁体   English

OpenCV C++:将大块白色像素转换为黑色

[英]OpenCV C++: Convert big block of white pixels to black

I am new to OpenCV, so apologies if I am not able to express my issue properly.我是 OpenCV 的新手,如果我无法正确表达我的问题,我深表歉意。

So, I have an image that I converted to B&W.所以,我有一张我转换为黑白的图像。 Now I want to convert all big block (block could be of any shapes) of white pixels to black and leave the small white pixels as it is.现在我想将白色像素的所有大块(块可以是任何形状)转换为黑色,并将白色小像素保持原样。

To further explain, please look at the picture below: This pic为了进一步解释,请看下面的图片:这张图片

This is from another stackoverflow post but basically what I want to do is get rid of that white box and just have text in my picture.这是来自另一个stackoverflow帖子,但基本上我想做的是摆脱那个白框,只在我的图片中添加文字。 In this picture, I can just put a black box on the top since I know where that white box is but how can I do it when I don't know where that white box is?在这张图片中,我可以在顶部放一个黑框,因为我知道那个白框在哪里,但是如果我不知道那个白框在哪里,我该怎么做呢?

Thanks in advance提前致谢

Edit: An example of a picture that I want is here编辑:我想要的图片示例在这里

You can use minArearect function.您可以使用minArearect函数。 This function draws fitted rectangles for each contour.此函数为每个轮廓绘制拟合矩形。 You can filter by setting these rectangle edge lengths.您可以通过设置这些矩形边长进行过滤。

        #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);
        }

Source image:源图像:

在此处输入图片说明

Points:积分:

在此处输入图片说明

Result:结果:

在此处输入图片说明

  1. Find contours.寻找轮廓。
  2. For each contour: cv::Rect br = cv::boundingRect(contour)对于每个轮廓: cv::Rect br = cv::boundingRect(contour)
  3. bwImage(br) = cv::Scalar(0, 0, 0) bwImage(br) = cv::Scalar(0, 0, 0)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM