«Взлом» SmartDeblur 2.2

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

    Берём испорченную шевелёнкой картинку



    Прогоняем через демоверсию SmartDeblur и получаем



    Замечаем водяные знаки, которые нам не нравятся. Если повторить эксперимент несколько раз с одной и той же исходной картинкой, то видно, что знаки очень статичны: не меняется ни текст, ни положение надписей. Значит, для наложения водяных знаков SmartDeblur просто применяет какую-то маску. Какую именно? Очень легко узнать! Подсовываем программе белое поле такого же размера, как исходная картинка. Переключаем в режим исправления размытия Гаусса с радиусом 0.1 и получаем



    Это и есть искомая маска. Пространство между надписями, кстати, не совсем белое, хм, ну ладно… Вычисления будем производить в системе RGB с целочисленными значениями от 0 до 255, в общем, без экзотики. Экспериментально удалось определить, что маска накладывается по формуле Rout = Rin * Rmask ÷ 255, где Rin — значение красного канала до наложения маски, Rmask — значение красного канала самой маски, Rout — значение красного канала, получаемое в результате наложения маски, ÷ — целочисленное деление. Для зелёного и синего каналов то же самое. В графических редакторах такой способ обычно называется просто "умножение".

    Против "умножения" будем применять "деление". Правда, с потерей точности. Вычисляем по обратной формуле Rin = Rout * 255 ÷ Rmask и видим



    Кое-какие следы всё-таки остались. То ли виновата потеря точности, то ли я немного ошибся в формулах. Но теперь водяные знаки не так резко бросаются в глаза, чего для наших целей вполне достаточно. И будем благодарны автору программы SmartDeblur за комментарии.
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 24

    • UFO just landed and posted this here
        +11
        Да я, по сути, ничего и не ломал. Даже не пользовался дизассемблером. Лишь производил вычисления над результатами работы программы, и то с потерей точности.
          +17
          Теперь автор сделает наложение водяных знаков случайным образом по изображению, и всё :)
            +7
            Автору советую ещё и делать буквы в надписях из случайного шума.
              +13
              А вот положение надписей если и менять случайным образом, то очень осторожно. Иначе я несколько раз прогоню одну и ту же картинку через программу и соберу результат из тех кусочков, на которых нет надписи.
                +9
                Ещё рацпредложение: вычислять все "случайности" из хэша исходной картинки. Тогда бесполезно и прогонять картинку несколько раз, и белое поле вместо неё подсовывать.
                  +15
                  Спасибо за предложения! Возможно, поменяю алгоритм наложения водяных знаков.
                  Собственно, защита как таковая у SmartDeblur'а без особых наворотов по принципу «кто не хочет купить, все равно не купит».
                  Если нужен ключик — пишите, чтобы не мучится каждый раз с удалением маски )
                    +1
                    Спасибо. Ключик пока не нужен, выручает фотоштатив. А вот почему в маске пространство между надписями не совсем белое — интересно. Это результат деконволюции белого поля или просто маска такая?
                      0
                      Маска не имеет фона. А вот процессы поиска ядра, деконволюции и пост-фильтрации всегда вносят какие-то искажения в виде звона, небольшого изменения тона, шума и пр.
                        0
                        Спасибо.
                      +3
                      Вот как я это делаю в своем приложении (Java):
                      private void putWaterMark(Mat alpha){
                      	String logo = _applicationName;
                      	String subLogo = "Free version";
                      	double fontScale = 1;
                      	double maxFontScale = 15;
                      	int thickness = 7;
                      	int [] baseline = {0};
                      	// начало текста по горизонтали
                      	double x = Math.random() * alpha.cols()/10+15;
                      
                      	// начало текста по вертикали
                      	double y1 = alpha.rows() / 10.;
                      	double y2 = alpha.rows() * 0.9;
                      	double y = y1 + Math.random() * (y2 - y1); 
                      		
                      	Point beginLogo = new Point(x,y);
                      		
                      	// максимальная ширина текста
                      	int maxLength = alpha.cols() - (int) beginLogo.x;
                      		
                      	// подбор размера фонта под ширину текста:
                      	Size textsize = new Size(100,100);
                      	for (double d=maxFontScale; d>0; d = d - 0.5){
                      		textsize = Core.getTextSize(logo, Core.FONT_HERSHEY_COMPLEX, d, thickness, baseline);
                      		if (textsize.width < maxLength) {
                      			fontScale = d;
                      			break;
                      		}
                      	}
                      		
                      	Core.putText(alpha, logo, beginLogo, Core.FONT_HERSHEY_COMPLEX, fontScale, new Scalar(255), thickness);
                      	beginLogo.y = beginLogo.y + textsize.height;
                      	Core.putText(alpha, subLogo, beginLogo, Core.FONT_HERSHEY_COMPLEX, fontScale/2, new Scalar(255), thickness-3);
                      }
                      


                      Я использую в приложении библиотеку OpenCV, поэтому она же применена здесь при наложении текста.
                      На входе пустое изображение (Mat alpha) того же размера как исходное, только в градациях серого (однобайтное). На выходе на него наложен требуемый текст. И сейчас это изображение можно накладывать на исходное. Как — зависит от конкретной реализации, вот у меня здесь есть немного про наложение картинок.
                      Вот, кстати результат наложения:
                      image
                      +1
                      Тут тоже не всё очевидно, ведь при реализации вашего предложения «в лоб» изменение одной точки где-то в углу может сдвинуть все надписи. Тогда опять можно будет просто собрать картинку по кусочкам.
                        0
                        Практически из любого подхода с наложением водяных знаков можно собрать изображение по кусочкам. Поэтому обычно реализуют стандартное наложение даже в фотостоках.
                          +1
                          Да. Даже если положение надписей постоянно, а меняется лишь шум в буквах, то можно попытаться собрать статистику и вычислить кое-какой результат. В общем, согласен с вами, что хэшировать надо с умом.
                          +4
                          Не поможет. Многократно меняем 1 пикс в картинке (например верхний левый) — хэш меняется, и задача сводится к рецепту mporshnev.

                          Можно для демо-версии не всю картинку «шарпить», а например только верхнюю половинку. Предвосхищая «добавить снизу белое поле, потом обрезать» — думаю, не прокатит, т.к. это повлияет на поиск пути смазывания, так что результат не будет эквивалентен. Да, можно повернуть и повторить, потом склеить… ну еще можно кружочками.

                          Или, к примеру, лимит по разрешению ставить.
                +5
                Класс! Использование программы для её же эксплойтинга. Замечательно придумано!
                Это как через IDA дизасмить её же (платную).
                  +2
                  Всегда хотел сделать что-то подобное с фотографиями фотостоков. Но дальше мыслей «хм, надо как-нибудь попробовать» никогда не делал. Вы молодец :)
                    0
                    SmartDeblur же открытая была? Теперь закрытая, да ещё и с водяными знаками?
                    0
                    Эх, сделал бы кто-то простую программу для Super Resolution. Или попросту чтобы после пары кликов мышкой можно было бы вычленить чуть более качественынй кусок из последовательности кадров
                      0
                      Да, это было бы хорошо для кадров с видео.
                      Это, пожалуй, самый частый вопрос по SmartDeblur'у — как восстановить нечитаемый номер с регистратора или уличной камеры
                        +1
                        У меня примерно та же задача, только с портретом злоумышленника, ломился тут один на днях… Впрочем все эти задачи от экономии на камерах/регистраторах
                      0
                      Тут задача простая, потому что можно применить водную метку к пустому изображению. Веселее подбирать шрифты, воссоздавать фотошоповские эффекты и их разворачивать (прозрачность, тень...). Вот развлекался (очень давно):

                      превью

                      Было: i31.tinypic.com/2e0rayf.jpg
                      Стало: i27.tinypic.com/eaf9ue.jpg

                      Очень огорчает, когда замечательные фотографии и рисунки оскверняются конскими метками…

                      Only users with full accounts can post comments. Log in, please.