Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: b0noI от Апрель 21, 2011, 00:25



Название: Выделение темногго объекта на белом фоне
Отправлено: b0noI от Апрель 21, 2011, 00:25
Задача стала, к которой не знаю как подойти( :
дан рисунок - на белом фоне есть темный (черный) квадрта (около 5 на 5 см). Необходимо четко выделить изображение в середине квадрата (внутри квадрата может быть рисунок, цвет и т.д.). Есть ли какое либо простое решение? Qt знаю не один год но с графикой ничего пока не делал.

В идеале можно пройтись каким то образом по белому фону до первого темного пикселая. Однако как выделить именно темный пиксель.

Буду очень благодарен если хоть дадите направление где капать. Спасибо


Название: Re: Выделение темногго объекта на белом фоне
Отправлено: m_ax от Апрель 21, 2011, 01:24
Задача стала, к которой не знаю как подойти( :
дан рисунок - на белом фоне есть темный (черный) квадрта (около 5 на 5 см). Необходимо четко выделить изображение в середине квадрата (внутри квадрата может быть рисунок, цвет и т.д.). Есть ли какое либо простое решение? Qt знаю не один год но с графикой ничего пока не делал.

В идеале можно пройтись каким то образом по белому фону до первого темного пикселая. Однако как выделить именно темный пиксель.

Буду очень благодарен если хоть дадите направление где капать. Спасибо

Что значит чётко выделить изображение? Убрать чёрный квадрат, но оставить рисунок?
Или что?


Название: Re: Выделение темногго объекта на белом фоне
Отправлено: b0noI от Апрель 21, 2011, 23:21
Задача стала, к которой не знаю как подойти( :
дан рисунок - на белом фоне есть темный (черный) квадрта (около 5 на 5 см). Необходимо четко выделить изображение в середине квадрата (внутри квадрата может быть рисунок, цвет и т.д.). Есть ли какое либо простое решение? Qt знаю не один год но с графикой ничего пока не делал.

В идеале можно пройтись каким то образом по белому фону до первого темного пикселая. Однако как выделить именно темный пиксель.

Буду очень благодарен если хоть дадите направление где капать. Спасибо

Что значит чётко выделить изображение? Убрать чёрный квадрат, но оставить рисунок?
Или что?

Дано 1.png (вложение)
Надо получить 2.png (вложение)


Название: Re: Выделение темногго объекта на белом фоне
Отправлено: Denjs от Апрель 21, 2011, 23:44
Во первых, у вас на рисунке не квадрат  ::) ;)

во вторых, если квадрат всегда "горизонтален", его размер всегда больше Z пикселей, толщина стенки Y такова, что всегда толще 1 "четко черного" пикселя (ну вдруг там на границах размытие), для определения верхней границы бегите по одному "пикселю" вниз по каждой Z/2-й колонке пока не встретите "абсолютно черный пиксель". потом к этому значению прибавьте Y и полечине внутреннюю верхнюю границу.

Аналогично - бегите вправо по одному пикселю по каждой Z/2-й строке.

у вас будут 2 внутренние границы - верхняя и левая.


Дальше сами догадаетесь что делать?


Название: Re: Выделение темногго объекта на белом фоне
Отправлено: b0noI от Апрель 21, 2011, 23:48
Во первых, у вас на рисунке не квадрат  ::) ;)

во вторых, если квадрат всегда "горизонтален", его размер всегда больше Z пикселей, толщина стенки Y такова, что всегда толще 1 "четко черного" пикселя (ну вдруг там на границах размытие), для определения верхней границы бегите по одному "пикселю" вниз по каждой Z/2-й колонке пока не встретите "абсолютно черный пиксель". потом к этому значению прибавьте Y и полечине внутреннюю верхнюю границу.

Аналогично - бегите вправо по одному пикселю по каждой Z/2-й строке.

у вас будут 2 внутренние границы - верхняя и левая.

Дальше сами догадаетесь что делать?

Благодарю Вас. Эта часть алгоритма мне понятна, но так как я ранее на Qt не трогла граффику вообще, то вопрос тут такой: как именно в Qt проверить пиксель, являеться ли он читсо черным? что лучше использовать что бы быстро пробижаться по пикселям картинки?


Название: Re: Выделение темногго объекта на белом фоне
Отправлено: Denjs от Апрель 21, 2011, 23:56
Цитировать
как именно в Qt проверить пиксель
ну скажем
Код:
QRgb QImage::pixel ( int x, int y ) 

далее
Код:
QColor(QRgb rgb )
а далее - смотрите по каждому каналу уровень.
Код:
int QColor::blue () const
аналогично red() green()
Если все 3 уровня меньше какого-нить порогового значения то это и считаем черным пикселем... не?

как быстро? ну это уже другой вопрос...
можно QRgb не приводить к QColor а сразу маскировать по битовым маскам и сдвигать.

Как нибудь так... не? :
Код:
//QRgb это #AARRGGBB :: An ARGB quadruplet on the format #AARRGGBB, equivalent to an unsigned int.
QRgb color;
int colorGreen=(color & 0x0000FF00)>>16;


Название: Re: Выделение темногго объекта на белом фоне
Отправлено: b0noI от Апрель 22, 2011, 00:05
Цитировать
как именно в Qt проверить пиксель
ну скажем
Код:
QRgb QImage::pixel ( int x, int y ) 

далее
Код:
QColor(QRgb rgb )
а далее - смотрите по каждому каналу уровень.
Код:
int QColor::blue () const
аналогично red() green()
Если все 3 уровня меньше какого-нить порогового значения то это и считаем черным пикселем... не?

как быстро? ну это уже другой вопрос...


Спасибо огромное это точно сдвинет дело с мертвой точки и даст начало)


Название: Re: Выделение темногго объекта на белом фоне
Отправлено: b0noI от Апрель 26, 2011, 09:58
Цитировать
как именно в Qt проверить пиксель
ну скажем
Код:
QRgb QImage::pixel ( int x, int y ) 

далее
Код:
QColor(QRgb rgb )
а далее - смотрите по каждому каналу уровень.
Код:
int QColor::blue () const
аналогично red() green()
Если все 3 уровня меньше какого-нить порогового значения то это и считаем черным пикселем... не?

как быстро? ну это уже другой вопрос...
можно QRgb не приводить к QColor а сразу маскировать по битовым маскам и сдвигать.

Как нибудь так... не? :
Код:
//QRgb это #AARRGGBB :: An ARGB quadruplet on the format #AARRGGBB, equivalent to an unsigned int.
QRgb color;
int colorGreen=(color & 0x0000FF00)>>16;

Добрый день)) проект вроде продвинулся, однако реализуя по указанному примеру появилась вновь небольшая проблемка:

Вот функция которая показывает есть ли в строке пикселей черный пиксель и она работает (line - номер строки рисунка которая проверяеться):

Код:
if (line > 0 && line < img.height())
    {
        for (int i=0;i<img.width();i++)
        {
            QColor color(img.pixel(i,line));
            if (color.black() >= this->RGBBlack)
                return true;
        }
    }
    return false;

А вот функция которая показывает черный ли какой то конкретный пиксель в изображении:

 
Код:
if (x <= img.width() && y <= img.height())
    {
        QColor color(img.pixel(x,y));
        if (color.black() >= this->RGBBlack)
            return true;
    }
    return false;

и она уже совершенно не коректно работает. (this->RGBBlack = 250). Спасибо за разяснение вопроса) Особенно интересно какой порог и как подобрать для this->RGBBlack )


Название: Re: Выделение темногго объекта на белом фоне
Отправлено: Denjs от Апрель 26, 2011, 10:53
Во первых вы сами смотрели-то что там у вас в color.black()?

в ассистанте, вполне себе введение есть про цветовые пространства.
Как только вы поймете "что это" и как цвет может быть смоделирован - эти вопросы отпадут сами.

Black - из цветового пространства CMYK. Черный в CMYK может быть не только (0,0,0,255), но и (255,255,255,0) (залили тремы красками на бумагу все - получили черный. За это в издательствах по моему по голове бью за такие макеты, но серный от этого в вашем примере не становится белее)

Не могу сказать точно за QColor - но мне кажется у вас скорее всего RGB. Преобразовывать не пытайтесь - они не однозначны (RGB больше) (т.е. оно преобразуется, но тона вобщем случае могут измениться)

Берите QRgb или сравнивайте 3 компоненты -
Цитировать
Если все 3 уровня меньше какого-нить порогового значения то это и считаем черным пикселем... не?
почему так не делаете? )))

и примеры у вас кажется идентичные....


Название: Re: Выделение темногго объекта на белом фоне
Отправлено: Igors от Апрель 26, 2011, 13:58
1) Нужен критерий типа пиксель "выделяемый" или "фоновый" - лучше сразу зарядить это в ф-цию

2) вряд ли Вы получите много счастья "обведя" просто пиксель. Если я правильно понял, речь идет о группах/колониях пикселей которые образуют некоторый "примитив" - вот его и надо обвести

3) Как/чем выделять - тоже должно подстраиваться

Если мои предположения верны, то прямоугольники для выделения находятся так:

- идете по пикселям. Если пиксель "фоновый" - поехали дальше,

- иначе проверяем есть ли у него в "выделяемые" соседи. Если нет - заводим новый примитив для выделения, его прямоугольник = размер пикселя + 1

- иначе проверяем может ли пиксель быть добавлен в уже имеющиеся примитивы. Здесь одним просмотром прямоугольников не обойтись, лучше сразу зарядить "маску"

- после окончания просмотра обводим все примитивы