Данный пост создан исключительно с целью продемонстрировать, что реактор может иметь встроенный баян / разработка :: длиннопост :: баянометр

баянометр разработка длиннопост 

Данный пост создан исключительно с целью продемонстрировать, что реактор может иметь встроенный баянометр приемлемой функциональности без существенных затрат на его реализацию и сервера. Он ни в коем случае не пытается бросить тень на существующий баянометр от ExtraDj - вполне возможно его баянометр в сто раз круче (я не знаю).

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

А недавно ещё и получил разрешение от Вождя. Что ж, доступа к коду сайта и базе у меня нет. Выкачивать весь его контент, чтобы собрать отдельный баянометр я особо желанием не горю. Но могу, по крайней мере, разобраться в ситуации и продемонстрировать Proof of concept.

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

Итак. Перцептивный хэш - похоже, то, что нам нужно. Проблема распространенная, поэтому сразу же нашлась библиотека, которая этот хэш считает - по крайней мере эту рутину писать не придётся. Как будто мы ещё ничего не сделали, а решение уже готово. Протестируем.

Первый кадр из видео. Разрешение 720х1280 против 320х568.

■ Demo application ImageHash
□
X
: [[«*>■ Dl ^ [□]	. {o}6 I (2) <
AverageHash DifferenceHash Perceptual Hash
Browse
Load
Clear
73051550389305359
1112177781819418778
14419936282921065570
AverageHash DifferenceHash PerceptualHash Browse Load
Clear
73051550389305359
1112177781817321882

AverageHash и PerceptualHash - абсолютно одинаковые цифры. А это значит, что если вы сохраните этот хэш в БД рядом с картинкой, вы легко сможете достать по нему запись о картинке. Похоже баянометр в простейшем виде уже готов.

Извлечение данных. Т.к. некоторые реакторчане ссылались на проблему поиска в большом количестве данных, нужно протестировать и это. Приблизительно 7000000 картинок есть на реакторе. Возьмём MS Sql server. Создадим таблицу с 7000000 записей со случайными цифрами в качестве хэша. Чтобы всё было по-честному:

□ SELECT a,b
FROM ( SELECT TOP 200 a,b FROM test ORDER BY a DESC) SQ ORDER BY a ASC
.00 % -
И Результаты		ijl Сообщения
	a	b
1	! 6999800 !	6964075964389932
2	6999801	16589863736228552
3	6999802	5026461835299065
4	6999803	43764015194280080
5	6999804	62220703321801248
6	6999805

Изменим одно из значение на реальный хэш с картинки выше. И посмотрим сколько надо времени чтобы её найти.

SET STATISTICS TIME ON
select * from test where b=73051550389305359 JO %	-
IS Pe3yjibTaTbi		ill Coo6mehMH
A		B
1	2000000	73051550389305359,баянометр,разработка,длиннопост
SET STATISTICS TIME ON
select from test where b-73051550389305359
.00 % -
Щ Результаты Ф Сообщения
Время синтаксического анализа и компиляции SQL Server зремя ЦП = 0 мс, истекшее зремя = 0 мс.
Зремя работы SQL Server:
Зремя ЦП = 0 мс, затраченное зремя = 0 мс.
Зремя синтаксического анализа

По-моему проблем тут нет.

Дальше. Что если картинка немного отличается от оригинала. Например нам надо сравнить первый кадр видео с гифкой. Гифка, будет иметь кучу артефактов и, возможно, другой начальный кадр. Как тут:

■ Demo application ImageHash
AverageHash
DifferenceHash
PerceptualHash
Load
Clear
9205852151309271098
16177214717387634018
18072312633476747566
Browse
AverageHash
DifferenceHash
PerceptualHash
Browse Load Clear
9205852151334436986
17913352390918829410

Либо яркость на картинке выкручена на максимум, как тут:

' uemo application imagenasn
i
AverageHash	73051550389305359
DifferenceHash			1112177781819418778		
Perceptual Hash			14419936282921065570	89% 97%	
Browse	Load	Clear		Calculate	







AverageHash
■	DifferenceHash		
	Perceptual Hash		
	Browse	Load	Clear
218292640519487501

Хэши не совпадают. Всё пропало? Не совсем. Обратите внимание на подсчёт "похожести" хэшей внизу картинок. Всё что нам нужно сделать, чтобы начать находить не только идентичные картинки, но ещё и похожие - это перенести логику подсчёта похожести в запрос к БД. Получим.

|SET STATISTICS TIME ON
DECLARE @b Bigint = 73051550389305359
select from test where 64 Bit_Count(b @b))	100	64)>92
100 % -
® Pe3>^bTaTbi	ill Coo6mehMH
A	B
1 ! 100	218292640519487501
2 2000000	73051550389305359,баянометр,разработка,длиннопост
SET STATISTICS TIME ON
DECLARE @b Bigint = 73051550389305359
select from test where ((64 - Bit_Count(b A @b))	100 / 64)>92
.00 % -
Щ Результаты Ф Сообщения
Зремя скятахскчесхого анализа и компиляции SQL Server: время ЦП = 0 мс, истекшее время = 0 мс.
Зремя работы SQL Server:
Зремя ЦП = 0

Теперь по затратам времени и ресурсов. На этот Proof of concept ушло несколько часов - большая часть на подготовку и написание поста. Добавить его на любой свой сайт я могу за несколько часов. Нагрузку на сервер вы можете видеть в статистике запроса к БД. По-моему скромному мнению - она никакая. А если учесть, что эти запросы будут редкими - только при создании новых постов, то ими вообще можно пренебречь. Железу, на котором запущен sql сервер более пяти лет. Более того, пять лет назад это был бюджетный домашний комп.


Подробнее
■ Demo application ImageHash □ X : [[«*>■ Dl ^ [□] . {o}6 I (2) < AverageHash DifferenceHash Perceptual Hash Browse Load Clear 73051550389305359 1112177781819418778 14419936282921065570 AverageHash DifferenceHash PerceptualHash Browse Load Clear 73051550389305359 1112177781817321882 14419936282921065570
□ SELECT a,b FROM ( SELECT TOP 200 a,b FROM test ORDER BY a DESC) SQ ORDER BY a ASC .00 % - И Результаты ijl Сообщения a b 1 ! 6999800 ! 6964075964389932 2 6999801 16589863736228552 3 6999802 5026461835299065 4 6999803 43764015194280080 5 6999804 62220703321801248 6 6999805 51186298552502032 7 6999806 61729895769931216 8 6999807 82675927285693728 9 6999808 44555474440545928 10 6999809 73696997693270512 11 6999810 57798575477564824 12 6999811 20431419486669356 13 6999812 43146819658691952 14 6999813 35928559030316176 15 6999814 39734955841941616 16 6999815 80569026079814032 17 6999816 50544532603241472
SET STATISTICS TIME ON select * from test where b=73051550389305359 JO % - IS Pe3yjibTaTbi ill Coo6mehMH A B 1 2000000 73051550389305359
SET STATISTICS TIME ON select from test where b-73051550389305359 .00 % - Щ Результаты Ф Сообщения Время синтаксического анализа и компиляции SQL Server зремя ЦП = 0 мс, истекшее зремя = 0 мс. Зремя работы SQL Server: Зремя ЦП = 0 мс, затраченное зремя = 0 мс. Зремя синтаксического анализа и компиляции SQL Server зремя ЦП = 0 мс, истекшее зремя = 0 мс. (затронута одна строка) Зремя работы SQL Server: Зремя ЦП = 793 мс, затраченное зремя = 239 мс. Зремя выполнения: 2023-09-23Т12:25:10.4435617+03:00
■ Demo application ImageHash AverageHash DifferenceHash PerceptualHash Load Clear 9205852151309271098 16177214717387634018 18072312633476747566 Browse AverageHash DifferenceHash PerceptualHash Browse Load Clear 9205852151334436986 17913352390918829410 18072312616296878383
' uemo application imagenasn i AverageHash 73051550389305359 DifferenceHash 1112177781819418778 Perceptual Hash 14419936282921065570 89% 97% Browse Load Clear Calculate AverageHash ■ DifferenceHash Perceptual Hash Browse Load Clear 218292640519487501 10335549818690439451 14419953874838674530
|SET STATISTICS TIME ON DECLARE @b Bigint = 73051550389305359 select from test where 64 Bit_Count(b @b)) 100 64)>92 100 % - ® Pe3>^bTaTbi ill Coo6mehMH A B 1 ! 100 218292640519487501 2 2000000 73051550389305359
SET STATISTICS TIME ON DECLARE @b Bigint = 73051550389305359 select from test where ((64 - Bit_Count(b A @b)) 100 / 64)>92 .00 % - Щ Результаты Ф Сообщения Зремя скятахскчесхого анализа и компиляции SQL Server: время ЦП = 0 мс, истекшее время = 0 мс. Зремя работы SQL Server: Зремя ЦП = 0 мс, затраченное зремя = 0 мс. Зремя работы SQL Server: Зремя ЦП = 0 мс, затраченное зремя = 0 мс. (затронуто строк: 2) Зремя работы SQL Server: Зремя ЦП = 921 мс, затраченное зремя = 25€ мс. Зремя выполнения: 2023-09-23Т12:24:01.0136403+03:00
баянометр,разработка,длиннопост
Еще на тему
Развернуть
А если отразить зеркально картинку? Или кропнуть слегка? :D
stass-1 stass-1 28.09.202313:49 ответить ссылка 3.7

Отражение нормально не отследить, самая распространенная проблема это кропы с текстом или без текста

Raline Raline 28.09.202313:56 ответить ссылка 8.6
Почему отражение не отследить, а если при загрузке картинки создавать ее отзеркаленную копию и тоже проводить сравнение или так не делают сейчас?
Потому что почти всегда отзеркаленное изображение не единственное объект на картинке, оно сопровождается текстом или ещё какими-то небольшими элементами, которые были добавлены после отзеркаливания
Raline Raline 28.09.202314:35 ответить ссылка 2.0
Тогда это не баян
Ага даже баян в контексте исторических событий может стать не баяном, то есть обрести актуальность, но баяноблюстители и слышать об этом не хотят.
Меня посетила мысль сделать тег актуальный баян, но это лазейка для боянопостеров
и самое распространённое решение её - вычислять несколько хешей, для 4х вариантов переворота, 4х вариантов отражения, и нескольких вариантов кропа, например 14 пикселей снизу (под плашку реактора), несколько кропов под рамки аля-демотиватор, чб-вариант, и др. Это конечно решение "в лоб" и раздувает базу, но настолько стильно, и при разных оптимизациях и правильной настройке базы хотя бы в плане индексов, 7000000*10 это не проблема
Ascard Ascard 28.09.202314:12 ответить ссылка 2.8

Можно наоборот. Делать все варианты изображение на входе и уже эти варианты искать в бд.

я про это и сказал
Ascard Ascard 28.09.202314:22 ответить ссылка -0.1
нет. Вы сказали про то что для каждого варианта изображения(зеркала перевороты) хранить хэш в бд. Я говорю хранить только 1 вариант.
и как это по твоему работать должно? хеш и пхеш от отзеркаленного изображения будут разными. если хранить один пхеш, к примеру от "оригинала", то пхеш отзеркаленного варианта никогда не будет найден в таком варианте.
Ascard Ascard 28.09.202314:29 ответить ссылка 0.1
Легко.. У Вас есть изображение которое Вы хотите загрузить на реактор. Алгоритм делает все варианты этого изображения (которые вы хотите хранить в бд) и считает нужные алгоритму хэши и ищет их в бд. Все
именно это я и сказал
и нет, я предлагал хранить изображения в бд, ибо это изначально бред бредовый
Ascard Ascard 28.09.202314:34 ответить ссылка -0.5
> Это конечно решение "в лоб" и раздувает базу, но настолько стильно, и при разных оптимизациях и правильной настройке базы хотя бы в плане индексов, 7000000*10 это не проблема
ну да, ну да.
даже не пытайся прикопаться, я не первый год в этом вашем айти, и вариант хранить в базе картинки а не их хеши для поиска по хешам мне в голову не мог прийти даже в страшном-влажном сне. если тебе показалось что под "раздувает базу" имелось ввиду раздувание базы картинками а не хешами, то увы, ничем не могу помочь
Ascard Ascard 28.09.202314:40 ответить ссылка -0.8
тебя спрашивают не "зачем хранить картинки", а "зачем хранить миллиард хешей". Перестань уже в глаза долбиться.
И да, я знаю, что это ускоряет работу в рантайме за счет раздувания базы, но поскольку считать эти хеши все равно кудахтеру юзера всем похуй.
ну так и я повторю свой вопрос: как это по твоему работать должно?
вариант картинки и сама картинка могут иметь разные пхеши, и чтобы найти их в базе они должны в базе быть, и если кроп или слабый ресайз ещё можно найти хеммингом то отражения, большие рамки, и цветокоррекция могут менять пхеш полность. я так понимаю ты предлагаешь вычислить пачку таких вариантов прямо у юзера, это понятно и логично. а дальше? ну заслал ты пхеш отражённой картинки на сервер, а там его нет, там только пхеш оригинала. и? что дальше?
Ascard Ascard 28.09.202314:55 ответить ссылка -1.3
при сравнении двух картинок, "а" и "б" для каждой из картинок возможно n вариаций(например 8, 4 поворота * 2 отражения). Совпадающими картинками являются такие "а" и "б", которые имеют хотя бы одну совпадающую пару хешей для своих наборов вариаций.
Фокус в том, что для совпадающих картинок будет, в идеале, n пар совпадающих хешей.
Но получение этих n пар избыточно, нам достаточно одной.
Таким образом, вместо того чтобы высчитывать n для обоих изображений и потом сравнивать их между собой(между прочим, n^2, не хуй собачий), ты можешь высчитать 1(прописью - один) хеш для первой картинки и n для второй. И тупо сравнить этот единственный хеш первой картинки со всеми полученными хешами из вариаций второй. Первое же сильное совпадение означает, что картинка более или менее совпадающая.
Таким образом, хранить n хешей нет смысла, достаточно хранить тот самый 1 хеш, а n для второй картинки считать при валидации. Для юзера это дольше, чем наоборот, но проблемы индейцев как известно шерифа не ебут.

Так вот, вся эта телега по большому счету написана в один вопрос выше по треду, который ты читать отказываешься из каких-то религиозных соображений.
А_тред_я_читаю_жопой.jpg
возможно и жопой, у всех бывает. но отвечать я не отказываюсь, поэтому повтори пожалуйста вопрос, спасибо.
Ascard Ascard 28.09.202315:34 ответить ссылка -0.4
> Можно наоборот. Делать все варианты изображение на входе и уже эти варианты искать в бд.

первое же совпадение даст найденный повтор. простой in.
пусть так, просто соглашусь. видать я действительно что-то прочитал жопой и не так понял. или не так донёс свою мысль, как я её сам понимаю. прошу пардону и предлагаю на этот ветку закончить. спор ради срача мне не интересен
Ascard Ascard 28.09.202315:42 ответить ссылка -0.7
Ну тут вопрос: если считается n хэшей для каждого нового поста чтобы сравнить с единственным в базе, то... если расчитывать будет сервер, то что еще затратней: рассчитать n хэшей для уже 100% загруженной картинки(тем самым раздув БД и усложнив запросы) или считать n хэшей на каждую ПОПЫТКУ загрузки картинку - тут открываются хорошие возможностии для ДДОС атаки.
Если считать хэш на фронте(не знаю может ли такое JS), то тут могут погрустнеть юзеры с старыми тормозными мобилками допустим.
frenzy frenzy 30.09.202312:02 ответить ссылка 0.0
Можно считать разные хэши, многие игнорируют кропы/повороты. Посчитали 3 хэша (простой, colorhash, ну и какой-нибудь RadialVariance), их хватит чтоб достаточно точно картинку найти. Они толерантны каждый к своим искажениям, вместе должны делать что нужно.
Psilon Psilon 28.09.202315:06 ответить ссылка 0.1
Отражение уже работает, и в этом нет ничего проблематичного. Основная проблема - кроп
meh, риахтур не сохраняет коменты при закрытии формы, но думаю и так понятно:

Простой вариант:
1. Группируем изображения по диапазонах размеров.
2. Для каждого диапазона задаем размер squareH.
3. Берем центр изображения, вокруг него строим квадрат со стороной squareH, по которому и считаем хэш.

Количество диапазонов и допуск - вопрос эмпирический, без статистики загрузки картинок могу только пальцем в небо тыкать.
"Можно, делай" (с)
Chaosit Chaosit 28.09.202313:51 ответить ссылка 9.4
Как сделать, если нет доступа к телу... коду?
MaXM00D MaXM00D 28.09.202314:07 ответить ссылка 12.8
мое дело маленькое
я одно время тоже думал написать свой краулер и парсер для контента с джоя, но потом прикинул сколько это будет стоить денег и забил (покачто)
вместо этого написал расширение к хрому которое на сайтах с картинками, где я пасусь за контентом, добавляет кнопку поискать в баянометре (пока что мучаю творение ExtraDj, но потом прикручу ещё творение Коматоза), открывается диаложик и там сразу результаты поиска. ничего никуда не накопировать-сохранять-переносить. выдираю картинку сразу из вёрстки, ресайзю её до 512 по большей из сторон (чтобы не трахать канал диджею многомегабайтными png-ами), и шлю fetche-м прямо из браузера. стильно, модно, молодёжно. скрин как выглядит прилагается, кнопка с знакомой инокой видна и рядом с ней её наглядный переключатель созраняющий в базу (прямо в браузере) факт что картинка уже запощена (чтобы повторно не искать).
что касается самого реактора, то баянометр в нём встроенный и так есть, некоторые картинки при попытке запостить рубаются самим реактором. но паходу там что-то простое и примитивное, да и недоступное через graphql (чтобы сразу запросом к апи реактора проверять есть такое уже или нет). а жаль.
ггш
Вауапоте^
Пост 5647722
[Download now]

Проверить
OK
2878	27	74
Views	Comments Favor
+ Fav	Download
Category	All /All
Species	Unspecified / An
Gender	Any
Size	2000x1333
Ratio	3.873
JR? Check	w
Spuydjeks
See more from Spuydji
Ascard Ascard 28.09.202314:05 ответить ссылка 4.5
Второй запрос - это же full scan без использования индексов? Тогда почему он такой быстрый? Не понимать.
может хеши отсортированы?
madgod madgod 28.09.202314:35 ответить ссылка 0.6
может они даже, о ужас, cекционированы? и оптимизированы для поиска по расстоянию хеминга, как это у коматоза сделано? и ещё кешить чуток на стороне браузера можно, и прочий изврат
Ascard Ascard 28.09.202314:43 ответить ссылка 1.7
Слава технологиям!
ты ещё учти что не все алгоритмы перцептивного хеша дают на выходе одинаковые варианты. либы вычисляют что-то своё, совместимое только с собой. в том смысле что вычислить пачку пхеш-ей в браузере и заслать их на сервер для поиска, может не сработать. на это наткнулся тот же коматоз (мы с ним в привате общались за это) в своём баянометре. у него даже круче было, когда использованная сишная либа начала давать другие результаты после пересборки из сорцов и поиск вообще отвалился, пока вся база не перехишировалась. а перехеш базы означает что нужно или все картинки хранить у себя, все 70000-сколько-там или выкаивать заново
Ascard Ascard 28.09.202314:33 ответить ссылка 0.4
а если пилить свой оригинальный контент то и всё это дрочево с баянометрами не нужно...
то-то ты много оригинального, я смотрю, напилил
Ascard Ascard 28.09.202314:56 ответить ссылка 1.7
не много но своё
ну, что же
тогда молодец, умничка, продолжай в том же духе
Ascard Ascard 28.09.202317:34 ответить ссылка -0.4
Да нет ничего плохого в том чтобы реактор был агрегатором прикалюх. Нужно просто концепцию контента адаптировать с учётом баянов. Не надо их бояться, презирать и ненавидеть. Надо сделать систему саморегулируемой. Например:
1. Если кто то постит баян, любой можно указать оригинальный пост в отдельной форме.
2. Если пост вылез на главную и модер подтверждает, что это баян, он выбирает какой из двух вариантов поста остаётся (на тот случай если новый в лучшем качестве или там с описанием и тегами нормальными) и этот пост остаётся на месте свежезалиого баяна за авторством исходного пользака.
3. Вся новая карма суммируется со старой и большая часть уходит в пользу изначального автора поста, и по чуть чуть тому кто отметил баян и кто его обработал.
4. Все старые комменты сворачиваются какой нибудь спойлер под постом и если что их можно и развернуть и продолжить комментить. Либо в новых комментах писать.

Таким образом кармадрочерам-боянистам не будет профита, если их поймают. А их поймают, потому что на реакторе всегда кто то бдит.
Просто боянистам будет приятно, что пост зря не пропал хороший: кто пропустил - оценит, кто забыл - ещё раз угарнёт если реально прикол.
Первоначальный постер получает почти всю новую карму, ему особо приятно.
Полицейский баянов и модер тоже не в накладе, доброе дело на службе порядка сделали, кармы чутка получили, медальки какие нибдь за выслугу лет нацепили.

Так и меньше бардака, и экономия дискового пространства, и социально-положительный момент.

А если ещё дубли тегов объединять....
Odin Odin 28.09.202322:29 ответить ссылка 1.5
aHash, как и dHash - кусок дерьма. Они дают огрмное количество ложно положительных результатов
То что ты описал - практически полное описание того, как работает что мой баянометр, что каматоза. Только я использую pHash, с всякими плюшками, а у каматоза там какой то другой алгоритм, но суть не особо меняеться. Можно ли это интегрировать в реактор? Да, конечно. Хочет ли этим заниматься кока? Разумееться нет, иначе оно уже давно было бы реализовано
ExtraDJ ExtraDJ 28.09.202321:15 ответить ссылка 3.6

Вождь говорил что у них ресурсов сейчас нет, а не желания этим заниматься. И я могу понять, когда речь идёт о таких ресурсах. Возможно, им пока не нужны «всякие плюшки», если они требуют таких ресурсов. А вот в виде, описанном в посте, с вполне приемлемым функционалом и практически без затрат каких-либо «ресурсов» баянометр можно было бы и сделать.

А вообще, это их ресурс - их дело. Я сделал вроде всё, что мог, чтобы они об этом задумались.

Пост который я написал - иная технология, на основе SURF/SIFT/ORB. Существующий баянометр использует pHash, который не такой требовательный к ресурсам. Это старая, дешёвая, рабочая технология. Мой баянометр требует 2 виртуальных ядра и гигов 6 оперативы. На этих мощностях скорость поиска по одной картинке занимает менее 100мс. Можно эти требования сократить в 2 раза, но ценой увеличения времени поиска примерно до секунды на картинку. Выделить 6 гигов в рамках выделенного сервера - не проблема, потому, было бы желание
Встроенный баянометр- это было бы круто
Только зарегистрированные и активированные пользователи могут добавлять комментарии.
Похожие темы

Похожие посты
SeaBIOS (version re 1-1.S.3-0-ge2fc41e-prebuiIt.qemu-project.org) Machine UUID 24d5244c-48ec-4475-8a41-ade944c4e00c Booting from Hard Disk...
Boot failed: not a bootable disk
No bootable device. Retrying in 1 seconds.
iayanometr:/srv # touch test
touch: cannot touch 'test': Read-only file sy
подробнее»

баянометр длиннопост

SeaBIOS (version re 1-1.S.3-0-ge2fc41e-prebuiIt.qemu-project.org) Machine UUID 24d5244c-48ec-4475-8a41-ade944c4e00c Booting from Hard Disk... Boot failed: not a bootable disk No bootable device. Retrying in 1 seconds. iayanometr:/srv # touch test touch: cannot touch 'test': Read-only file sy