OpenCV C ++: конвертировать большой блок белых пикселей в черный - PullRequest
2 голосов
/ 10 февраля 2020

Я новичок в OpenCV, поэтому извиняюсь, если не могу express правильно решить мою проблему.

Итак, у меня есть изображение, которое я преобразовал в черно-белый. Теперь я хочу преобразовать весь большой блок (блок может иметь любую форму) белых пикселей в черный и оставить маленькие белые пиксели такими, как есть.

Для более подробного объяснения, пожалуйста, посмотрите на картинку ниже: Этот пи c

Это из другого поста stackoverflow, но в основном я хочу избавиться от этого. этой белой коробки и просто текст на моей картинке. На этой картинке я могу просто поставить черный ящик сверху, так как я знаю, где находится этот белый ящик, но как я могу это сделать, если не знаю, где находится этот белый ящик?

Заранее спасибо

Редактировать: пример изображения, которое я хочу, это здесь

Ответы [ 2 ]

1 голос
/ 10 февраля 2020

Вы можете использовать функцию minArearect . Эта функция dr aws устанавливает прямоугольники для каждого контура. Вы можете фильтровать, устанавливая эти длины прямоугольника.

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

Исходное изображение:

enter image description here

Очки:

enter image description here

Результат:

enter image description here

0 голосов
/ 10 февраля 2020
  1. Поиск контуров.
  2. Для каждого контура: cv :: Rect br = cv :: boundingRect (контур)
  3. bwImage (br) = cv :: Scalar (0, 0, 0)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...