У меня проблема с тем, что у меня есть шаблон , где необходимо заполнить 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;
}
}
}
}