Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > VB6 > Подсчет пятен |
Автор: Mephisto 4.9.2003, 17:57 |
Люди, есть вопрос. Как можно посчитать количество пятен на рисунке? Сложность в том, что исходной картинкой является фотография, и пятна имеют разный размер. Спасибо всем кто ответит. |
Автор: cardinal 4.9.2003, 21:06 |
Если под пятнами ты подразумеваешь темные места на картинке, то предется выдумывать какой нибудь хитрый алгоритм (врятли ты готовый найдешь, я вещи и по стандартней не мог найти ![]() ![]() Во первых есть два метода определить яркость цвета: - яркость определяется по формуле: (max + min) / 2, при этом max и min это максимальное и минимальное значения из твоего RGB цвета. Что-то не получилось лучше сформулировать ![]() - А второй метод это определение яркости по формуле, которая определяет яркость наиболее близкою к яркости, которую воспринимаем мы. Вот формула: Яркость = R * 0,3 + G * 0,59 + B * 0,11 Красный у тебя будет потемнее в два раза по этой формуле, а белый как был так и останется самым ярким (+/- погрешность если будешь работать без плавующей точки). Во-вторых ты можешь сделать два буфера. При первом просмотре картинки ты запишешь в первый буфер яркости твоих точек, а при втором просмотре ты будешь писать в буфер номер пятна. Вобщем у тебя должен в конце концов быть такой результат: ----------------------------------------------------- ----11111------------------------------------------ -------111111------------------2222222--------- ------11111111---------------------2222222---- ----------1111111------------------22222222--- --------------------------------------------222222 -------------------------------------22222222222 ----333333333------------------------------------ ---------333333333------------------------------- ---------3333333333333------------------------- Ну и соответственно самая большая цифра второго буфера это и есть количество пятен на твоем рисунке. Успехов! |
Автор: Black_Star 9.9.2003, 23:36 | ||
Я что-то не понял насчет определения яркости ![]()
255 - максимум, верю. Но 255 - минимум??? Найдем мы, например, число 100... получается (100+255)/2=177.5 ? хм... это еще куда не шло... а найдем 1! 1 - это почти ничто, а получим в итоге 128! Это будет резко отличаться от действительности... Предлагаю такой вариант, но он слишком долгий... Просматриваем всю картинку... A1=Point(x,y) A2=Point(x+1,y) A3=Point(x-1,y) ... ... A9=Point(x+1,y+1) Далее хитрым уравнением находим среднее значение всех цветов, это и будет цвет в точке х,у. |
Автор: cardinal 10.9.2003, 12:20 | ||||||
Полностью согласен ![]()
Дело в том, что число 100 или 1 мы не найдем ![]()
У белого цвета значения всех каналов равны, соответственно равны и значения min и маx. |
Автор: Black_Star 10.9.2003, 19:52 | ||||||
![]() ![]()
Вопрос. Почему яркость не бывает больше 240??? ![]()
Предлагаю тоже ![]() ![]() |
Автор: cardinal 11.9.2003, 03:07 | ||||
Ответ. А кто сказал, что paint так же яркость высчитывает, как я это предложил. Они сказали, что самое яркое значение - это 240, вот и все.
Ну а тут мы уже от темы отклоняемся ![]() |
Автор: Black_Star 11.9.2003, 23:04 |
Да, но понятие яркости такое размытое... Яркость - не что иное, как сам цвет. Просто надо высчитывать значение соотв. цвета (0-255). И ничего делить не надо ![]() Возьми просто красный RGB(255,0,0) но он может быть и RGB(100,0,0) просто кажется, что тускнее... Но это изменение не яркости, а самого цвета! А потому вычислить его яркость или неяркость нереально... В моем 1м примере я предлагал сравнивать текущую точку с окружающими... Мотом брать "среднее". Но это будет типа метода Blur. А для бооольших пятен надо ваще нечто выдумывать.... ![]() А то, что менять яркость.... приведет к ZOrder картинки ![]() |
Автор: cardinal 12.9.2003, 01:07 | ||||
Ничего тут размытого нет! Как же dithering работает, если яркость - это размытое понятие?
Ну тогда напиши, как ты хочешь высчитывать это значение соотв. цвета (0-255). ![]() |
Автор: Black_Star 12.9.2003, 14:43 | ||
А что там сложного? RGB=&h980000 ,т.е. красный равен 155... надо умеличить его "яркость" ставь. например 200... И что, сложно? Но это не яркость! Это изменение самого цвета!!! |
Автор: cardinal 12.9.2003, 15:59 | ||||
Я же вычисляю а ты говоришь нереально ![]() Ладно, переходим к практике. Вот есть у тебя на картинке круг цвета RGB(236,102,79), внутри него есть еще один круг меньшего диаметра - его цвет RGB(207,50,22), внутри него есть еще один круг (тоже меньшего диаметра) цвета RGB(146,35,16). Так вот круг в самом центре очень темный, соответсвенно это и есть пятно. Используя метод (min+max)/2, получаем для трех кругов такие значения: 157, 114, 81. Соответсвенно мы можем сказать, что все что темнее 100 (<100) - это пятна. А теперь твоя очередь, Black_Star потому, что я так и не въехал, что ты предлагаешь делать. Вот еще раз то, что ты написал:
|
Автор: -Mikle- 13.9.2003, 12:41 |
Black_Star, cardinal абсолютно прав. Естественно для реального значения цвета разные RGB, но задача в том, чтобы определить темнее-светлее. Если рассматривать просто составляющие RGB, то ты не сможешь определить насколько один цвет темнее-светлее другого. Поэтому нужна формула, которая взяв три составляющие, вернула одно число. Наиболее верный результат яркости будет по известной всем формуле: Яркость = R * 0,3 + G * 0,59 + B * 0,11, упомянутой cardinal'ом, так как даст разный результат для значений: RGB(0,0,255) и RGB(0,255,0). cardinal, + за терпеливость ![]() |
Автор: -Mikle- 13.9.2003, 12:49 |
Ну вот... воткнули проверку... теперь тебе нет плюса за терпеливость, простите, еще 440 сообщений надо, чтоб я мог человеку репутацию поднять... ![]() Admin, не многовато-ли 500? Может хотя-бы 100 сделаешь? Если чел ответил 100 раз, значит он уже не просто "прохожий" на форуме... Ну да ладно, решать тебе... ![]() |
Автор: Black_Star 14.9.2003, 04:07 |
Темнее/светлее понятно... 3 составляющие никто рассматривать не собирался ![]() ![]() ![]() ![]() Нет такого в действительности - ЯРКОСТИ !!! Нету... и не будет... это просто цвет... у пущай он хоть триганом. фо-ми высчитывается, всеравно это не яркость, а цвет... просто светлее... Вай... Не интересно с вами спорить - уперлись! ![]() Ладно, каждый остался при своих интересах ![]() ![]() ![]() |
Автор: cardinal 14.9.2003, 16:20 | ||||
Хорошо, взяли красный RGB(255,0,0). Посчитали то, что ты называешь цветом
Конечно уперлись ![]() ![]() |
Автор: Black_Star 14.9.2003, 20:32 |
127,0,0 - красный. Однозначно ![]() 0,127,0 - зеленый... и т.д. |
Автор: cardinal 14.9.2003, 21:13 |
Так цвет получается неопределенный! Какой все таки цвет ты получаешь (один цвет): красный или зеленый? Не красный и не зеленый, а цвет с яркостью 127 ![]() |
Автор: Black_Star 14.9.2003, 21:26 |
:Е Достал... пусть будет ЯРКОСТЬ !!! Но если сам цвет 255, то яркость 127 - "тусклость" ! Это ладно... Возьми цвет желтый RGB(255,255,0)... То RGB(127,127,0) похож на темный желтый, но ужасно... |
Автор: -Mikle- 15.9.2003, 17:09 | ||||
Вы друг друга не понимаете ![]() cardinal, Black_Star прав, он говорит о том, что в RGB нет такого понятия как яркость, есть цвет из разных уровней 3 составляющих. Black_Star, cardinal прав, он совсем и не доказывает что есть яркость у RGB, он просто говорит что пятно, для нашего глаза, это такой цвет, который при переводе в серые полутона, воспринимается нашим глазом темнее, чем другие. Например зеленый воздействует на сетчатку "мощнее", чем синий. Вообще тема - это подсчет пятен. Реализовать это проще всего рассматривая картинку как черно-белое изображение, не вдаваясь в то, какого цвета сами пятна. В ЧБ картинке все три составляющие равны, и определяют, как бы, яркость белого цвета. Ты прав Black_Star, с позиции программы это просто разные цвета, но мы ищем ПЯТНА, которые может увидеть наш глаз на чб картинке, а это значит, что нам надо найти места, которые для глаза темнее, т.е. значение любой из 3 составляющих ЧБ изображения, например, меньше 100. cardinal просто берет цвет и сразу рассматривает его как черно-белую точку, называя полученное значение яркостью(т.е. насколько эта точка для нашего глаза темнее-светлее). Вот и все! ![]()
Удачи! ![]() |
Автор: Mephisto 15.9.2003, 17:26 |
-Mikle- прав разница между яркостью и цветом не так уж и важна. Предложение -Mikle-а перевести в ч/б я уже пробовал. Напомню, что искомая картинка это отсканированая фотография из электромикроскопа ![]() ![]() Вообще есть идея: при встрече пятна изучать его размеры, затем брать его в простую фигуру(например круг) и заливать его каким-либо цветом например vbGreen, при следуещей встрече с vbGreen_ом просто проходить мимо. В результате количество таких заливок и будет искомое кол-во пятен. Может у кого есть идеи проще? ![]() |
Автор: Mephisto 18.9.2003, 18:01 |
Люди, нужны ещё идеи. ![]() |
Автор: cardinal 18.9.2003, 20:07 |
Я если честно пока не понял, почему тебе не подошла та идея, которую я тебе еще в начале темы написал. Если картинки, которые ты сканируешь не очень большие, то кинь мне их на ящик, чтобы я понимал, что надо сделать получше. А если они здоровые, то вырежи фрагмент и кинь его на ящик. У меня просто подключение к инету не самое быстрое, да и ящик маленький ![]() |
Автор: Mephisto 22.9.2003, 18:01 |
OK в скором времени постараюсь вытащить фото в инет и сделать его доступным для всех. ![]() |
Автор: Mephisto 27.9.2003, 14:00 | ||||
Идея конечно супер, но....
Хорошо, но есть вопрос: как при переходе на следующую строчку определить является ли найденое пятно продолжением первого, либо это уже пятно номер 3? ![]() |
Автор: cardinal 27.9.2003, 17:13 |
Ты бегаешь по строчкам слева направо, соответственно если слево от точки стоит цифра, то если if по темноте проходит, текущая точка будет с этим же номером. Если слева пусто, то ты смотришь на строчке выше. Если ты там найдешь на позициях (текущая точка - ширина bmp - 1) или (текущая точка - ширина bmp) или (текущая точка - ширина bmp + 1) каую нибудь цифру, то и текущей точке ты присваиваешь эту цифру, если нет, то это новое пятно. |
Автор: maxim1000 28.9.2003, 09:04 | ||
еще нужно предучмотреть механизм объединения пятен: это придется делать в случае U-образных пятен например, обработанные строки будут такие: 00000000000000000000 00000111100000220000 00001111100022222000 00000111100022200000 00000001110022200000 а следующая строчка: 000000000*****000000 |
Автор: cardinal 28.9.2003, 12:47 | ||
Да, maxim1000, есть такое дело. Спасибо, за дельный совет!
А механизм прост. Надо только переделать немного то, что я описал сверху ![]() Ты бегаешь по строчкам слева направо, соответственно если слево от точки стоит цифра, то если if по темноте проходит, текущая точка будет с этим же номером. Если слева от точки стоит цифра и ты находишь на строчке выше на позициях (текущая точка - ширина bmp - 1) или (текущая точка - ширина bmp) или (текущая точка - ширина bmp + 1) какую нибудь цифру, то значит мы имеем U-образное пятно. Ту цифру, которую мы нашли сверху (и остальные такие же в буфере) мы заменяем на цифру, которая находится слева от точки. Если слева пусто, то ты смотришь на строчке выше. Если ты там найдешь на позициях (текущая точка - ширина bmp - 1) или (текущая точка - ширина bmp) или (текущая точка - ширина bmp + 1) какую нибудь цифру, то и текущей точке ты присваиваешь эту цифру, если нет, то это новое пятно. Ну и буфер (мне вот сейчас в голову пришло) надо сделать на две точки шире, чем сама картинка, тогда не надо будет бесконечно проверять на краю ты находишься или нет. Начинать надо в правильном месте и прыгать по строчкам тоже. |
Автор: Mephisto 29.9.2003, 15:12 |
Спасибо всем кто ответил! Проблема подсчета пятен почти реализована. Осталось только тестировать. Поступила новая задача, более сложная: Имеется более плотная упаковка, необходимо так же подсчитать количество. Но сдесь это гораздо сложнее выполнить. Ну вобщем сами смотрите... ![]() Разные размеры картинок: http://grafitchem.narod.ru/Small_Grafit.htm 75x100 (3.8 kb) http://grafitchem.narod.ru/Resize_of_Grafit.htm 301x400 (32.9 kb) http://grafitchem.narod.ru/Grafit.htm 2029x2696 (399.3 kb) Если есть какие идеи, то... За раннее спасибо. |
Автор: cardinal 29.9.2003, 15:50 | ||
Ну и что нам с ним делать? Ты сам писать функцию начинай, а если что поможем! |
Автор: Mephisto 29.9.2003, 17:16 | ||||
Да, прикольно получилось. ![]() Это была версия для редактирования. Если картинка не подгружается, то можете посмотреть картинку по указанным адрессам. ![]() |
Автор: cardinal 29.9.2003, 22:13 |
Дааааа... Пятна оказывается не разделены четко, что делает все немного сложнее. Ну тогда есть такое предложение: Бегаешь по строчкам и ищешь какую нибудь светлую точку. Это будет что-нибудь типа середины пятна. От этой точки ты идешь вправо, вниз, влево и вверх пока не наткнешься на темную точку. Эти темные точки будут крайними точками пятна. Потом ты объединяешь эти четыре крайних точки, делая из них например прямоугольник. Этот прямоугольник будет приблизительно площадью, которую занимает пятно. Ну а потом, как ты уже и говорил можешь его залить, чтобы потом ясно было, где ты уже пятно отметил. Ну и так далее... Короче главное тут выбрать светлую границу и темную границу по которым ты и будешь определять "середина" это пятна или крайняя точка. В конце концов количество заливок - это и есть кол-во пятен +/- столько-то пятен (зависит от размера картинки). Но это дело такое. В конце концов потом ты можешь пробежать картинку четыре раза: с верхней левой точки, с верхней правой точки, с нижней левой точки и с нижней правой точки (ну чтобы каждый раз получались разные заливки), а результаты поделить на четыре. Я думаю результат будет неплохим. Только вот жалко тебя ![]() Успехов! |
Автор: Mephisto 1.10.2003, 15:46 |
Спасибо тебе cardinal за идею. Знаешь, ты почти прочитал мои мысли. ![]() Также совпала почти реализованная идея на счет углов. Я пытаюсь пройти по картинке сначала сверху-вниз, а затем со всех углов. ![]() |
Автор: neutrino 2.10.2003, 11:09 |
Можно вопрос: на этой картинке пятна - это эти выпоклости или что? И тебе надо подсчитать количество выпуклостей? |
Автор: Mephisto 2.10.2003, 16:27 | ||
Да! Плюс (в идеале) подсчитать площадь. ![]() |
Автор: cardinal 2.10.2003, 17:50 | ||
А я про квадрат ничего не говорил ![]() ![]() Вот так... |