Обнаружение 7-сегментных символов на изображении - PullRequest
0 голосов
/ 20 апреля 2020

У меня проблема с тем, что у меня есть шаблон , где необходимо заполнить 7-сегментные дисплеи, используя цифры с левой стороны от них. Я пишу программу, которая должна найти каждый из этих сегментов и затем что-то с ними сделать.

Я начинаю с того, что превращаю изображение в градации серого и пороговую его (содержащую только значения 0 и 255) и выполняю горизонтальную гистограмму сегментация, чтобы найти строки, а затем вертикальная сегментация гистограммы, чтобы найти столбцы, которые окружают сегменты, которые в теории должны дать мне точные границы для каждого сегмента.

Однако программа, которую я написал, работала, но это не было «Правильный» способ, поскольку я добавил жестко закодированные значения, которые не зависят от разрешения и качества изображения. Кроме того, я просто заблокирован и не могу найти способ настроить логи c всей системы. Например, если вы посмотрите поближе, вы увидите, что внутри некоторых сегментов есть несколько пустых столбцов, потому что есть 5 разных версий, а некоторые имеют свои мини-сегменты (я имею в виду часть отображения одного символа) дальше друг от друга и не полностью подключен, что приводит к тому, что моя программа находит 0 или близко к 0 пикселям с любыми значениями в некоторых столбцах для этой строки. Я также вычисляю среднее значение столбцов в определенной строке, чтобы найти вертикальные границы каждого символа, но это не работает так, как я ожидал (я полагаю, по причинам, о которых я говорил ранее).

Я добавлю свой код, но попросил бы кого-нибудь, кто решил потратить свое время и ответить на эту тему, что, если они не уверены в том, как исправить МОЙ код, возможно, они дадут мне другие идеи, используя те же методы (вертикальная и горизонтальная гистограмма). сегментация).

Шаблоны всегда будут выглядеть так и могут отличаться только в зависимости от того, как кто-то их заполнил, или если они немного повернуты. Результат должен выглядеть следующим образом: this .

CODE:

public List<SegmentLine> findHorizontalSegments(int[] rows, double rowMedian, double columnMedian) {
    List<Integer> horizontalLines = new ArrayList<>();

    // SegmentLine is a class that interprets each row on the image, in total there should be 15 of them for every image as there are 15 rows in total
    List<SegmentLine> segmentLines = new ArrayList<>();
    int counter = 0;

    // rowMedian is the number of white pixels on a black background divided by number of rows
    for (int i = 0; i < rows.length; i++) {
        // if number of white pixels in rows[i] is larger than the average, add this line to the lines of the current row
        if (rows[i] > rowMedian) {
            horizontalLines.add(i);
            counter = 0;
        }
        else {
            // a lot of randomness incoming
            // increase counter of lines that supposedly dont belong to the row
            counter++;
            if (counter > rows.length / 45) {
                if (horizontalLines.size() > rows.length / 45 ) segmentLines.add(new SegmentLine(horizontalLines));
                counter = 0;
                horizontalLines.clear();
            }
        }
    }
    return segmentLines;
}

// find vertical borders inside each row
public void findSegments(double[][] columnValues, List<SegmentLine> segmentLines) {
    int width = columnValues[0].length;

    for (SegmentLine line : segmentLines) {
        int start = line.getStart();
        int end = line.getEnd();
        double median = 0;

        // calculate median for current row
        for (int i = 0; i < width; i++) {
            median += columnValues[end][i] - columnValues[start][i];
        }
        median /= width;

        int xStart = 0;
        int xEnd = 0;
        int count = 0;
        int empty = 0;

        for (int i = 0; i < width; i++) {
            double columnValue = columnValues[end][i] - columnValues[start][i];
            if (columnValue >= median) {
                if (count == 0) {
                    xStart = i;
                }
                else xEnd = i;
                count++;
            }
            else {
                if (columnValue > 0) continue;
                else if (empty < 10) {
                    empty++;
                    continue;
                }
                if (count > 50) {
                    // create an object of class Segment with start and end x,y coordinates
                    line.addSegment(new Segment(start, end, xStart, xEnd));
                }
                count = 0;
                empty = 0;
            }
        }
    }
}
...