ANTICHAT.XYZ    VIDEO.ANTICHAT.XYZ    НОВЫЕ СООБЩЕНИЯ    ФОРУМ  
Баннер 1   Баннер 2
Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей. Здесь обсуждаются безопасность, программирование, технологии и многое другое. Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
Вернуться   Форум АНТИЧАТ > Программирование > PHP, PERL, MySQL, JavaScript
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

[PHP][HELP] Скелетонизация изображения
  #1  
Старый 21.03.2010, 01:42
draliokero
Познающий
Регистрация: 14.03.2009
Сообщений: 86
Провел на форуме:
385811

Репутация: 12
По умолчанию [PHP][HELP] Скелетонизация изображения



Помогите пожалуйста реализовать бинаризацию и скелетонизацию изображения с помощью GD.
Вот, что нарыл по скелетонизации http://dic.academic.ru/dic.nsf/ruwiki/683052 .

Последний раз редактировалось draliokero; 21.03.2010 в 03:23..
 
Ответить с цитированием

  #2  
Старый 21.03.2010, 03:22
draliokero
Познающий
Регистрация: 14.03.2009
Сообщений: 86
Провел на форуме:
385811

Репутация: 12
По умолчанию

Что касается бинаризации: нашел AS сценарий, из него выдернул принцип
Код:
<?php
$im = imagecreatefrompng("php.png");
$width = imagesx($im);
$height = imagesy($im);
for ($y = 0; $y < $height; $y++) {
    for ($x = 0; $x < $width; $x++) {
        if (imagecolorat($im, $x , $y) <= 0x7FFFFF) imagesetpixel($im, $x, $y, 0x000000);
        else imagesetpixel($im, $x, $y, 0xFFFFFF);
    } 
} 

header('Content-type: image/png');
imagepng($im);

Последний раз редактировалось draliokero; 21.03.2010 в 17:45..
 
Ответить с цитированием

  #3  
Старый 21.03.2010, 14:19
Gifts
Reservists Of Antichat - Level 6
Регистрация: 25.04.2008
Сообщений: 827
Провел на форуме:
2769640

Репутация: 1304


По умолчанию

draliokero Для малоцветных изображений (например чернобелых, или где цвета сосредоточены в узкой области) - будет возвращаться пустое изображение, наверное лучше вычислять ЧБ изображение, а потом находить среднюю яркость пиксела и уже относительно этой величины - бинаризировать изображение
__________________
Любая действущая программа устарела.
Создайте систему, которой сможет пользоваться даже дурак ,и только дурак захочет ею пользоваться.
Как правильно задавать вопросы: _http://www.yakimchuk.ru/questions.htm
 
Ответить с цитированием

  #4  
Старый 21.03.2010, 17:48
draliokero
Познающий
Регистрация: 14.03.2009
Сообщений: 86
Провел на форуме:
385811

Репутация: 12
По умолчанию

Gifts, сразу в поиск полез, как думаете этим вопрос решится http://bubble.ro/How_to_check_if_an_image_is_grayscale_in_PHP.html ?


На Google Code нашел С++ проект с фильтром скелетонизации (алгоритм Zhang Suen PDF на Google Docs (Редирект с tinyurl.com, потому что парсер режет [forbidden link])) переписал, получилось вот это:
PHP код:
<?php
$im 
imagecreatefrompng("php.png");
$width imagesx($im);
$height imagesy($im);
for (
$y 0$y $height$y++) {
    for (
$x 0$x $width$x++) {
        if (
imagecolorat($im$x $y) <= 0x7FFFFFimagesetpixel($im$x$y0x000000);
        else 
imagesetpixel($im$x$y0xFFFFFF);
    } 

// Функция скелетонизации бинарного изображения
function zhang_suen_thinning_iteration($im$condition_switch)
{
    global 
$width$height;

    
$running false;
    for(
$y 1$y $height 1$y++) {
        for(
$x 1$x $width 1$x++) {
            
$p1 imagecolorat($im$x$y) > 0;
            if (
$p1 0) {
                
$p2 imagecolorat($im$x$y 1) > 0;
                
$p3 imagecolorat($im$x 1$y 1) > 0;
                
$p4 imagecolorat($im$x 1$y) > 0;
                
$p5 imagecolorat($im$x 1$y 1) > 0;
                
$p6 imagecolorat($im$x$y 1) > 0;
                
$p7 imagecolorat($im$x 1$y 1) > 0;
                
$p8 imagecolorat($im$x 1$y) > 0;
                
$p9 imagecolorat($im$x 1$y 1) > 0;
                
$connectivity =
                (
$p2 == && $p3 == 0) +
                (
$p3 == && $p4 == 0) +
                (
$p4 == && $p5 == 0) +
                (
$p5 == && $p6 == 0) +
                (
$p6 == && $p7 == 0) +
                (
$p7 == && $p8 == 0) +
                (
$p8 == && $p9 == 0) +
                (
$p9 == && $p2 == 0);
                
$non_zero_neighbors $p2 $p3 $p4 $p5 $p6 $p7 $p8 $p9;

                if (
<= $non_zero_neighbors && $non_zero_neighbors <= && $connectivity == 1) {
                    if (
$condition_switch == true) {
                        if ((
$p2 $p4 $p6 == 0) && ($p4 $p6 $p8 == 0)) {
                            
imagesetpixel($im$x$y0x000000);
                            
$running true;
                        } 
                    } else {
                        if ((
$p2 $p4 $p8 == 0) && ($p2 $p6 $p8 == 0)) {
                            
imagesetpixel($im$x$y0x000000);
                            
$running true;
                        } 
                    } 
                } 
            } 
        } 
    } 
    return 
$running;


zhang_suen_thinning_iteration($imtrue);

header('Content-type: image/png');
imagepng($im);
Но работает как-то криво, с точностью на оборот – происходит не скелетонизации, а ожирение o_O

Есть на Java, Perl, C++, Pas куски из OCR модулей,
вот один из них: ZhangSuen.java
Вроде все понятно, может кто-нибудь поможет тогда исправить ошибку и доделать?

Последний раз редактировалось draliokero; 23.03.2010 в 01:21..
 
Ответить с цитированием

  #5  
Старый 21.03.2010, 21:06
Gifts
Reservists Of Antichat - Level 6
Регистрация: 25.04.2008
Сообщений: 827
Провел на форуме:
2769640

Репутация: 1304


По умолчанию

draliokero Изображение мы должны изменять только после завершения итерации. Из-за того что мы насилуем imageGD постоянно - код получается очень медленным, по хорошему - лучше при бинаризации создавать двумерный массив, а потом уже раскрашивать обратно. Работающий код, без оптимизации:

PHP код:
<?php

set_time_limit
(0);


$im imagecreatefrompng("skeleton.png");
$width imagesx($im);
$height imagesy($im);
for (
$y 0$y $height$y++) {
    for (
$x 0$x $width$x++) {
        if (
imagecolorat($im$x $y) <= 0x7FFFFFimagesetpixel($im$x$y0x000000);
        else 
imagesetpixel($im$x$y0xFFFFFF);
    } 

// Функция скелетонизации бинарного изображения
function zhang_suen_thinning_iteration($condition_switch)
{
    global 
$width$height$im;
    
    
$im2 imagecreatetruecolor($width$height);
    
    
$running false;
    for(
$y 1$y $height 1$y++) {
        for(
$x 1$x $width 1$x++) {
            
$p1 imagecolorat($im$x$y) > 0;
        
            if (
$p1 0) {
            
imagesetpixel($im2,$x,$y,0xFFFFFF);
                
$p2 imagecolorat($im$x$y 1) > 0;
                
$p3 imagecolorat($im$x 1$y 1) > 0;
                
$p4 imagecolorat($im$x 1$y) > 0;
                
$p5 imagecolorat($im$x 1$y 1) > 0;
                
$p6 imagecolorat($im$x$y 1) > 0;
                
$p7 imagecolorat($im$x 1$y 1) > 0;
                
$p8 imagecolorat($im$x 1$y) > 0;
                
$p9 imagecolorat($im$x 1$y 1) > 0;
                
$connectivity =
                (
$p2 == && $p3 == 0) +
                (
$p3 == && $p4 == 0) +
                (
$p4 == && $p5 == 0) +
                (
$p5 == && $p6 == 0) +
                (
$p6 == && $p7 == 0) +
                (
$p7 == && $p8 == 0) +
                (
$p8 == && $p9 == 0) +
                (
$p9 == && $p2 == 0);
                
$non_zero_neighbors $p2 $p3 $p4 $p5 $p6 $p7 $p8 $p9;

                if (
<= $non_zero_neighbors && $non_zero_neighbors <= && $connectivity == 1) {
                    if (
$condition_switch == true) {
                        if ((
$p2 $p4 $p6 == 0) && ($p4 $p6 $p8 == 0)) {
                            
imagesetpixel($im2$x$y0x000000);
                            
$running true;
                        } 
                    } else {
                        if ((
$p2 $p4 $p8 == 0) && ($p2 $p6 $p8 == 0)) {
                            
imagesetpixel($im2$x$y0x000000);
                            
$running true;
                        } 
                    } 
                } 
            } else 
imagesetpixel($im2$x$y0x000000);
        } 
    } 
    
imagecopy($im,$im2,0,0,0,0,$width,$height);
    return 
$running;

$flag true;$count 0;

//zhang_suen_thinning_iteration($im, $flag);
while (zhang_suen_thinning_iteration($im$flag = !$flag) && $count++ < 60) {}

header('Content-type: image/png');
imagepng($im);
За 60 итераций получаем такое изображение из левой верхней картинки первого поста (С увеличением чиасла итераций треугольник конечно пропадет, но достаточно не быстро):


З.Ы. получить ЧБ изображение можно через среднее арифметическое трех каналов цветного (что, кстати, и будет яркостью пиксела)
__________________
Любая действущая программа устарела.
Создайте систему, которой сможет пользоваться даже дурак ,и только дурак захочет ею пользоваться.
Как правильно задавать вопросы: _http://www.yakimchuk.ru/questions.htm

Последний раз редактировалось Gifts; 21.03.2010 в 21:12..
 
Ответить с цитированием

  #6  
Старый 22.03.2010, 23:35
Omegа
Новичок
Регистрация: 16.12.2009
Сообщений: 27
Провел на форуме:
203807

Репутация: 30
По умолчанию

Решил попробовать - вот что получилось =D

Код:
<?php
	header('Content-type: image/png');
	$im = imagecreatefrompng('FILE.PNG');
	$im0 = imagecreatefrompng('FILE.PNG');
	$w = imagesx($im);
	$h = imagesy($im);
	for($y=0;$y<$h;$y++) {
		for($x=0;$x<$w;$x++) {
			if((imagecolorat($im, $x, $y) & 0xFF)>(256/2)) {
				imagesetpixel($im,$x,$y,0xFFFFFF);
				imagesetpixel($im0,$x,$y,0xFFFFFF);
			} else {
				imagesetpixel($im,$x,$y,0x000000);
				imagesetpixel($im0,$x,$y,0x000000);
			}
		}
	}
	$open = false;
	for($y=0;$y<$h;$y++) {
		for($x=0;$x<$w;$x++) {
			if($open!=true) {
				if(imagecolorat($im,$x,$y)==0xFFFFFF) {
					$open=true;
					$start = $x;
				}
			} else {
				if(imagecolorat($im,$x,$y)==0x000000) {
					$open=false;
					$x0 = $x-1;
					$c = round(($start+$x0)/2);
					imageline($im,$start,$y,($c-1),$y,0x000000);
					imageline($im,($c+1),$y,$x0,$y,0x000000);
				}
			}
		}
	}
	$open=false;
	for($x=0;$x<$w;$x++) {
		for($y=0;$y<$h;$y++) {
			if($open!=true) {
				if(imagecolorat($im0,$x,$y)==0xFFFFFF) {
					$open=true;
					$start = $y;
				}
			} else {
				if(imagecolorat($im0,$x,$y)==0x000000) {
					$open=false;
					$y0 = $y-1;
					$c = round(($start+$y0)/2);
					imagesetpixel($im,$x,$c,0xFFFFFF);
				}
			}
		}
	}
	imagepng($im);
	imagedestroy($im);
?>
 
Ответить с цитированием
Ответ



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
NVIDIA создала систему трехмерного изображения tinyM Мировые новости 4 30.10.2009 22:57
Leica M9: дальномерная цифровая камера с полнокадровым датчиком изображения Keltos Новости мира "железа" 3 14.09.2009 14:23
Видеочипы могут строить изображения в тысячу раз быстрее пр KentPol Новости мира "железа" 0 18.08.2009 18:33
Xss без Xss k00p3r Чужие Статьи 5 08.09.2008 15:53
Изображения в интернете будут защищать "водяными знаками" dinar_007 Мировые новости 11 19.08.2006 04:34



Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT.XYZ