0

I want to find with OpenCV first red pixel and cut rest of picture on right of it.

For this moment I wrote this code, but it work very slow:

        int firstRedPixel = mat.Cols();
        int len = 0;


           for (int x = 0; x < mat.Rows(); x++)
            {
                for (int y = 0; y < mat.Cols(); y++)
                {
                    double[] rgb = mat.Get(x, y);
                    double r = rgb[0];
                    double g = rgb[1];
                    double b = rgb[2];

                    if ((r > 175) && (r > 2 * g) && (r > 2 * b))
                    {
                        if (len == 3)
                        {
                            firstRedPixel = y - len;
                            break;
                        }

                        len++;
                    }
                    else
                    {
                        len = 0;
                    }
                }
            }

Any solutions?

enter image description here

Kacper
  • 620
  • 1
  • 7
  • 16
  • Here is a general method to find the red : https://stackoverflow.com/questions/51229126/how-to-find-the-red-color-regions-using-opencv/51230291#51230291 – Kinght 金 Dec 06 '18 at 01:16

2 Answers2

2

This is not the way to work with computer vision. I know this, because I did it the same way.

One way to achieve your goal would be to use template matching with a red bar that you cut out of your image, and thus locate the red border, and cut it away.

Another would be to transfer to HSV space, filter out red content, and use contour finding to locate a large red structure, as you need it.

There are plenty of ways to do this. Looping yourself over pixel-values rarely is the right approach though, and you won't take advantage of sophisticated vectorisation or algorithms that way.

deets
  • 6,285
  • 29
  • 28
  • I suppose it is better to just train on whole sequence and then crop tail substring (3 positions) programmatically. I mean, all you need is to recognize number and their order. – eocron Dec 05 '18 at 18:53
  • I need to recognize only part on black background – Kacper Dec 05 '18 at 19:03
  • I would also focus on identifying the numbers - again template matching *can* help here - and then just lose the last two digits. – deets Dec 05 '18 at 19:10
2

You can:

1) find red pixels (see here)

enter image description here

2) get the bounding box of red pixels

enter image description here

3) crop your image

enter image description here

The code is in C++, but it's only OpenCV functions so it should not be difficult to port to Java:

#include <opencv2\opencv.hpp>

int main()
{
    cv::Mat3b img = cv::imread("path/to/img");

    // Find red pixels
    // https://stackoverflow.com/a/32523532/5008845
    cv::Mat3b bgr_inv = ~img;
    cv::Mat3b hsv_inv;
    cv::cvtColor(bgr_inv, hsv_inv, cv::COLOR_BGR2HSV);

    cv::Mat1b red_mask;
    inRange(hsv_inv, cv::Scalar(90 - 10, 70, 50), cv::Scalar(90 + 10, 255, 255), red_mask); // Cyan is 90

                                                                                            // Get the rect
    std::vector<cv::Point> red_points;
    cv::findNonZero(red_mask, red_points);

    cv::Rect red_area = cv::boundingRect(red_points);

    // Show green rectangle on red area
    cv::Mat3b out = img.clone();
    cv::rectangle(out, red_area, cv::Scalar(0, 255, 0));

    // Define the non red area
    cv::Rect not_red_area;
    not_red_area.x = 0;
    not_red_area.y = 0;
    not_red_area.width = red_area.x - 1;
    not_red_area.height = img.rows;

    // Crop away red area
    cv::Mat3b result = img(not_red_area);

    return 0;
}   
Miki
  • 40,887
  • 13
  • 123
  • 202