Есть изображения(ровная прямая линия может быть в любой стороны):
Необходимо вычислить с какой стороны находиться эта прямая(условно) линия и повернуть изображение, чтобы она была ВНИЗУ. Пробовал искать наибольшую длину, когда пиксели идут друг за другом, но получается очень медленно, так как 4 цикла на каждую нужно.
for (int X = 0; X < image.height()/2; X++) {
for (int Y = 0; Y < image.width(); Y++) {
if (QColor(image.pixel(X,Y)).name()=="#ffffff")
{
int i = Y+1;
int max_buffer;
while(QColor(image.pixel(X,i)).name()=="#ffffff")
{
max_buffer++;
i++;
}
if(max_buffer>max_top)
{
max_top = max_buffer;
}
}
}
}
Это цикл только для вверха, еще 3 для других сторон и затем сравнивать что больше и т.д. Читал, что можно методом квадратов это реализовать и сделать более оптимизировано. UPADETE:Изображение уже является бинарным(черно-белым, монохромным)!
Если срез всегда параллелен осям координат, то сканирующей линией с каждого направления посчитать количество белых пикселов в линии. Для среза это число по мере движения линии вырастет резко, ступенькой, для круглой стороны будет кривая - лежачая парабола - квадратный корень. Метод неустойчив даже к небольшому наклону.
Если направление среза произвольно, можно посчитать для изображения моменты Ху и оценить ориентацию. Иx вычисление есть, например, в OpenCV.
Что-то я о простейшем применении моментов не подумал - вычислить центр масс фрагмента, содержащего усеченный круг, и найти, в каком направлении белые пикселы кончаются ближе от этого центра. Это будет перпендикуляр к искомому срезу.
ll sumx = 0;
ll sumy = 0;
ll sumv = 0;
for (int y = 0; y < image.height(); y++) {
for (int x = 0; x < image.width(); x++) {
sumx += value[y][x] * x;
sumy += value[y][x] * y;
sumv += value[y][x];
}
}
masscenterx = sumx / sumv;
masscentery = sumy / sumv;
Насколько я понял, прямая линия на изображении может быть параллельна одной из сторон изображения. В этом случае предлагаю следующий алгоритм поиска:
Повторяем аналогично для четырех граней, искомая плоская грань соответствует той, где найденное количество белых пикселей максимальной.
Изображение для наглядности алгоритма:
Добавлю, что у вас очень большой оверхед на сравнение цвета, сначала конвертация в QColor
, потом конвертация в QString
и потом сравнение строк.
Я бы навскидку написал что-нибудь типа
QRgb pixel = image.pixel(X, Y);
if (qRed(pixel) == 255 && qGreen(pixel) == 255 && qBlue(pixel) == 255)
...
З.Ы. Немного подумал, по идее алгоритм устойчив к небольшому повороту изображения, но надо потестировать
З.Ы.Ы. Есть второй вариант алгоритма, можно посчитать набор расстояний от края картинки до первого встреченного белого пикселя, на какой грани разница между этими расстояниями будет минимальна, та грань является искомой. Какой из двух вариантов оптимальнее, предположить не могу, надо тестировать.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Есть два Java файла с одного пакетаПри при использование метода выдает ошибку "The method Print(String) is undefined for the type Hello"
Читая книгу "Программирование под Android" Брайна Харди, я столкнулся со следующим кодомСуществует класс синглтон:
Вроде все верно, но что-то не такЗадача на английском закоментирована в коде
В интернете не нашел ни описания, ни документации этой функцииЧто она делает? И есть ли другие аналоги ResourceMap? Например, я где то слышал что...