OpenCV C ++:将白色像素的大块转换为黑色 [英] OpenCV C++: Convert big block of white pixels to black

查看:56
本文介绍了OpenCV C ++:将白色像素的大块转换为黑色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

点:

结果:

I am new to OpenCV, so apologies if I am not able to express my issue properly.

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. 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. 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:

这篇关于OpenCV C ++:将白色像素的大块转换为黑色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆