LINUX.ORG.RU

Plain C phash

 ,


0

1

Решил вот, в виду освоения Сишечки, сделать phash для картинок. Если кто из адептов посмотрит и прокомментирует, буду признателен.

http://pastebin.com/Abw1Xvb0

Собирается так:

gcc -std=c99 -O2 -Wall -Wextra -Werror -pedantic -o phash `pkg-config --cflags --libs MagickWand` -lm phash.c


Считаю декларацию переменной не в начале блока моветоном (да закидайте меня ссаными тряпками)

mittorn ★★★★★
()
Ответ на: комментарий от mittorn

Считаю моветоном объявлять переменную без её инициализации.

Begemoth ★★★★★
()
Ответ на: комментарий от mix_mix

Ну и объясни нам почему ты считаешь дурным тоном повышать читаемость кода?

Потому-что деды воевали так писали, очевидно же. Кстати это не только повышает читаемость кода, но и может помогать компилятору с оптимизацией, т.к. зачастую переменные инициализируются дефолтным значением, а оно может и не понадобится (if/for/return/etc...).

anonymous
()
Ответ на: комментарий от mix_mix

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

MKuznetsov ★★★★★
()
Ответ на: комментарий от anonymous

Потому-что деды воевали так писали, очевидно же

А потом появился С99

Кстати это не только повышает читаемость кода

Это отдельная декларация переменной что ли повышает?

но и может помогать компилятору с оптимизацией, т.к. зачастую переменные инициализируются дефолтным значением, а оно может и не понадобится

узбагойся, dead store компилятор и без подсказок выкинет

annulen ★★★★★
()
Ответ на: комментарий от annulen

А потом появился С99

Спасибо, кэп.

Это отдельная декларация переменной что ли повышает?

Конечно. Это существенно уменьшает объем кода, который надо просмотреть глазами, чтоб увидеть где эта переменная инициализировалась и как используется. Я иногда даже в отдельные блоки выношу код, чтоб локализовать переменные (если этот блок не напрашивается на вынос в отдельную функцию).

узбагойся, dead store компилятор и без подсказок выкинет

Если это какой-нибудь gcc, а не tcc, например. Но видно ты с «экзотикой» никогда не работал.

anonymous
()
Ответ на: комментарий от MKuznetsov

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

Т.е. как только не хочешь все сваливать в одну кучу, и хочешь максимально изолировать отдельные части кода, - это признак зарождения спагетти-кода? Как-то не соотносится, верно? А признак зарождения спагетти-кода - это размазывание логики, неумение выделять отдельные подзадачи, переиспользование переменных для других целей (что поощряют переменные сваленные в кучу в начале), отсутствие комментариев, длинные функции, goto не к месту и т.д.

anonymous
()
Ответ на: комментарий от annulen

Посмотрел на асм, который генерит tcc, буээээ

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

anonymous
()
Ответ на: комментарий от mittorn

Считаю декларацию переменной не в начале блока моветоном

Сначала хотел строго под -std=c90 все сделать, но imagemagick оказался с99.

slendy
() автор топика
Ответ на: комментарий от mix_mix

В начале блока проще найти декларацию.
Если слишком большая функция - выдели внутри маленький блок {} и внутри объявляй локальные. Заодно сохранится совместимость с c90- компиляторами

mittorn ★★★★★
()
Ответ на: комментарий от MKuznetsov

1. Код надо комментировать.

Это да, но там кода немного совсем.

2. Надо придерживаться единого стиля

Не распарсил, что имеется ввиду?

slendy
() автор топика
Ответ на: комментарий от annulen

или lua

Там качество генерации не лучше.

Тем более качество твоего кода не требует вменяемого конпелятора, поэтому все рассуждения ничего не стоят, пока вменяемого кода нет.

AnonCxx
()

Код выглядит неплохо. Но что делает непонятно. Что такое вообще этот phash? И что за магия с этим wand? Это какая-то библиотека или ты сам написал?

hotpil ★★★★
()
Ответ на: комментарий от hotpil

Phash - перцептивный хэш. Характеристика графического файла, которая вычисляется из пикселей. Если отресайзить картинку, или внести небольшие изменения, файлы станут принципиально разные, но phash-ы будут отличаться не очень сильно. То есть, можно искать одинаковые по смыслу изображения в бинарно разных файлах.

Wand - это из imagemagick.org

slendy
() автор топика
Ответ на: комментарий от slendy

Это да, но там кода немного совсем.

в моментах когда начинает 4-х вложенный цикл или вычисляются функции с sin cos неплохо дать комент почему именно это так как сделанно.

Надо придерживаться единого стиля

Не распарсил, что имеется ввиду?

РавногоВидаСущности стоит_именовать_однотипно воВсём_файле_сИсходником && придерживатся :=: lpszВо_всёмПроекте.

ps/ а то такой вид что 1/2 скопипащенна из неизведаннного источника, или написана неким другим.

MKuznetsov ★★★★★
()
Ответ на: комментарий от MKuznetsov

в моментах когда начинает 4-х вложенный цикл или вычисляются функции с sin cos

Принимается, спасибо.

скопипащенна из неизведаннного источника, или написана неким другим.

Это я сам несколько лет назад на ruby. А верблюжье именование из api imagemagick.

slendy
() автор топика
Ответ на: комментарий от slendy

Это я сам несколько лет назад на ruby

давай ссылку, не стесняйся..в копипасте на самом деле нет ничего плохого. «вот был неплох код, и я его взял» лучше чем изобретение велосипеда. Кстати ссылка нужна не для копирастии, а чтоб тот кто после тебя мог пройти по ссылке и понять что в данном случае код действительно того стоил.

MKuznetsov ★★★★★
()
Ответ на: комментарий от MKuznetsov

Там было буквально тоже самое. Преобразование графики через RMagick биндинги и дискретное косинусное преобразование матрицы пикселей. Если интересна тема, то вот академический пдф: http://www.phash.org/docs/pubs/thesis_zauner.pdf

Еще можно сравнивать/искать по фрагменту изображения через дескрипторы. Нужно какое-нибудь computer vision, opencv например. Я проверял разные алгоритмы, лучший результат получается, кажется, с SIFT, не помню точно. Дескрипторов нужно много - 400-500. Получается, что для сравнения двух пикч, расстояние Хамминга нужно посчитать 160К-250К раз. Соответственно умножить на общее количество пикч. Довольно напряжно. Но вот есть еще пдф: https://www.cse.msu.edu/~alexliu/publications/HammingQuery/HammingQuery_ICDE2... Хэш разбивается на части, и эти части просто сравниваются - равно, не равно - это уже относительно быстро. Там есть формула зависимости величины хамминга и количества частей.

В общем, меня когда-то эта тема заинтересовала, и я довольно таки много нарыл. Всякие нюансы уже не помню, надо будет поискать скрипты со всем этим.

Тут ситуация какая. Меня сейчас больше интересуют сишные аспекты и coding style. Алгоритм phash-а я выбрал просто так, чтобы нечто знакомое и уж не совсем «хэлло, ворлд».

slendy
() автор топика
Ответ на: комментарий от mittorn

Я думал вы все вымерли. Кому придёт в голову искать декларацию в начале блока? Там где переменная используется, там и будут искать декларацию, там и только там она и должна быть.

slovazap ★★★★★
()
Ответ на: комментарий от slovazap

Действительно. Декларацию наиболее логично размещать рядом с инициализацией. И зачем вообще что-то искать, если vim сам найдёт? Какие-то проблемы пользователей неvimа.

anonymous
()
Ответ на: комментарий от slovazap

Выше в треде уже писали, во что превратится код, если там такие огромные блоки и декларация где попало.

mittorn ★★★★★
()
Ответ на: комментарий от MKuznetsov

Это если бы было принято использовать простые блоки (без if/while/for и т.п.) и, энивей, нужно объявлять сразу с инициализацией. Но их редко используют, и никому не удобно читать такое.

Kuzy ★★★
()
Ответ на: комментарий от Kuzy

Но их редко используют, и никому не удобно читать такое.

Их редко используют, потому что стараются вынести «простые» блоки в функции

annulen ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.