Найти самый левый, самый правый, самый высокий и самый нижний синий пиксель с помощью C ++ и opencv - PullRequest
2 голосов
/ 11 июля 2019

Я пытаюсь написать код с использованием c ++ и opencv, который бы распознавал, какой синий пиксель идет первым слева, справа, сверху и снизу.Вот картинка, которую я использую: blue lines on image

И я хочу получить такую ​​картинку: blue lines with extrema marked

Это мой код до сих пор, а я нетдействительно понимаю, почему это не работает.

    void findBluePixels(Mat& original, Point2f min_x, Point2f max_x, Point2f min_y, Point2f max_y) {
    //First I set every point to the beginning of the image
        min_x = Point(0, 0);
        max_x = Point(0, 0);
        min_y = Point(0, 0);
        max_y = Point(0, 0);
    //looking for the most left blue pixel (the blue pixel with the smallest x value)
    //we are going through every column and every row
        for (int col = 0; col < original.cols; col++) {
            for (int row = 0; row < original.rows; row++) {
    //we check for every pixel if the pixel is blue and if the column of the pixel is bigger or equal to the beginning of the image
    if (original.at<Vec3b>(row, col)[0] == 255 && 
    original.at<Vec3b>(row, col)[1] == 0 &&
 original.at<Vec3b>(row, col)[2] == 0 && col >= min_x.y) {
    //if yes we have new value for the min_x and we stop looking because we have found the most left blue pixel
        min_x = Point(row, col);
        break;
                }
            }
        }
    //looking for the most right blue pixel (the blue pixel with the biggest x value)
    //we are going through every column and every row
        for (int col = 0; col < original.cols; col++) {
            for (int row = 0; row < original.rows; row++) {
    //we check for every pixel if the pixel is blue and if the column of the pixel is bigger or equal to the beginning of the image
    if (original.at<Vec3b>(row, col)[0] == 255 && 
    original.at<Vec3b>(row, col)[1] == 0 && 
original.at<Vec3b>(row, col)[2] == 0 && col >= max_x.y) {
    //if yes we have new value for the max_x, but we don't break because we are looking for the biggest blue pixel
    //we continue to search until the end of the picture
    max_x = Point(row, col);
                }
            }
        }
    //looking for the highest blue pixel (the blue pixel with the smallest y value)
    //we are going through every row and every column
        for (int row = 0; row < original.rows; row++) {
            for (int col = 0; col < original.cols; col++) {
    //we check for every pixel if the pixel is blue and if the row of the pixel is bigger or equal to the beginning of the image
    if (original.at<Vec3b>(row, col)[0] == 255 && 
    original.at<Vec3b>(row, col)[1] == 0 &&
    original.at<Vec3b>(row, col)[2] == 0 && row >= min_y.x) {
    //if yes we have new value for the min_y and we stop looking because we have found the highest blue pixel
    min_y = Point(row, col);
    break;
                }
            }
        }
    //looking for the most down blue pixel (the blue pixel with the biggest y value)
    //we are going through every column and every row
        for (int row = 0; row < original.rows; row++) {
            for (int col = 0; col < original.cols; col++) {
    //we check for every pixel if the pixel is blue and if the row of the pixel is bigger or equal to the beginning of the image
    if (original.at<Vec3b>(row, col)[0] == 255 && 
    original.at<Vec3b>(row, col)[1] == 0 &&
    original.at<Vec3b>(row, col)[2] == 0 && row >= max_y.x) {
    //if yes we have new value for the max_y, but we don't break because we are looking for the biggest blue pixel
    //we continue to search until the end of the picture
    max_y = Point(row, col);
                }
            }
        }
    //Here I want to make green points on the pixels we have found
    circle(original, min_x, 3, Scalar(0, 255, 0), 8, LINE_AA);
    circle(original, max_x, 3, Scalar(0, 255, 0), 8, LINE_AA);
    circle(original, min_y, 3, Scalar(0, 255, 0), 8, LINE_AA);
    circle(original, max_y, 3, Scalar(0, 255, 0), 8, LINE_AA);
}

Точки, которые я получаю в конце, абсолютно случайны.

Я был бы очень признателен, если кто-то может помочь!:)

Ответы [ 2 ]

3 голосов
/ 11 июля 2019

Как уже упоминалось @nivpeled, но в коде.

void findBluePixels(Mat& original) {
    Point min_x = Point(original.cols, original.rows);
    Point min_y = Point(original.cols, original.rows);
    Point max_x = Point(-1, -1);
    Point max_y = Point(-1, -1);
    //looking for the most left blue pixel (the blue pixel with the smallest x value)
    //we are going through every column and every row

    const Vec3b blueColor(255, 0, 0);
    for (int row = 0; row < original.rows; row++) {
        for (int col = 0; col < original.cols; col++) {
            if (blueColor != original.at<Vec3b>(row, col))
                continue;

            if (min_x.x > col) {
                min_x = Point(col, row);
            }
            if (max_x.x < col) {
                max_x = Point(col, row);
            }

            if (min_y.y > row) {
                min_y = Point(col, row);
            }
            if (max_y.y < row) {
                max_y = Point(col, row);
            }
        }
    }
    //Here I want to make green points on the pixels we have found
    circle(original, min_x, 13, Scalar(0, 255, 0), 8, LINE_AA);
    circle(original, max_x, 13, Scalar(0, 255, 0), 8, LINE_AA);
    circle(original, min_y, 13, Scalar(0, 255, 0), 8, LINE_AA);
    circle(original, max_y, 13, Scalar(0, 255, 0), 8, LINE_AA);
}

result

Плюс некоторые рекомендации:

• Do для цикла первый для строкитогда для столбца .Компьютер работает намного быстрее, если вы получаете доступ к данным последовательно.Пример последовательности доступа с номером:

Faster ->
[ 1 2 3 ] 
[ 4 5 6 ] 
[ 7 8 9 ] 
Slower ->
[ 1 4 7 ] 
[ 2 5 8 ] 
[ 3 6 9 ]
1 голос
/ 11 июля 2019
  1. Вы должны выполнить цикл на матрице только один раз и выполнить все проверки внутри одного и того же (внутреннего) тела цикла.

  2. Предпочитаю использовать имена, а не цифры. например if (original.at (row, col) [СИНИЙ] == 255 вместо if (original.at (row, col) [0] == 255

  3. Пожалуйста, дважды проверьте индекс 0 в пикселе, действительно держите синее значение (не правда ли, RGB?)

  4. логические проблемы: если вы хотите найти, например, минимальный х, вы должны код (col

    if (... && col min_x = точка (строка, столбец); перерыв; }

и init следующим образом:

min_x = Point(MAX_COL, 0);
max_x = Point(MIN_COL, 0);
min_y = Point(0, MAX_ROW);
max_y = Point(0, MIN_ROW);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...