Найдите различия между двумя изображениями для приложений для демонстрации экрана

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

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

1) для сравнения изображений доступно много бесплатного кода и библиотеки, но я просто не понимаю, какой из них мне следует использовать, а какой будет намного быстрее для сравнения. так что просто расскажите мне об этом.

2) и самая важная часть - как отправить разницу только по сети и объединить разницу с фактическим изображением на другом конце

Я много пытался получить информацию о моем пункте 2, но не получил ничего похожего. я не нашел статьи, которая может подсказать мне, как отправить разницу только по сети и объединить разницу с фактическим изображением на другом конце

поэтому я специально ищу подробное обсуждение моего пункта 2. Благодарность


person Thomas    schedule 30.11.2012    source источник
comment
Итак, если у вас есть изображение, в котором верхняя половина изображает лошадь, а нижняя - человеческие ноги. На другом изображении верхняя половина - лошадь, нижняя - зебра. Вам нужны ножки зебры? Тогда что делать? Как бы вы слили разницу, поскольку они находятся в одном месте?   -  person LukeHennerley    schedule 30.11.2012
comment
скорость обновления экрана на другом конце медленная. Вы пытаетесь отправить видео по сети? Уже есть кодеки, которые упрощают обновление данных только кадра, какой кодек вы используете? или вы отправляете только изображения - если да, то в каком они формате?   -  person Kami    schedule 30.11.2012
comment
png формат. просто посоветуйте мне, как применить РАЗНИЦУ между двумя изображениями на настоящем изображении? это очень важно для меня знать.   -  person Thomas    schedule 30.11.2012


Ответы (3)


Вам нужно будет выполнить три шага:

  1. Создайте разницу (DIFF) двух последовательных изображений. Сравнение пикселей на пиксель двух изображений займет очень много времени. Вам следует использовать хорошо зарекомендовавшую себя библиотеку, такую ​​как OpenCV; ознакомьтесь с библиотекой Emgu CV (http://www.emgu.com/) для .NET: AbsDiff () должен быть тем методом, который вы ищете. Результат будет примерно таким: DIFF = IMG2 - IMG1.
  2. Отправьте DIFF по сети. Это по-прежнему полное изображение, но JPEG или PNG будут использовать свои возможности полного сжатия, предполагая, что это в основном черное изображение, то есть с небольшими изменениями. На самом деле это три подшага: Сжать - Отправить - Распаковать.
  3. Примените DIFF к текущему изображению. Получатель может рассчитать следующее изображение IMG2 = DIFF + IMG1. Это можно сделать с помощью EmguCV Добавить метод.
person Peopleware    schedule 30.11.2012
comment
спасибо за помощь, но этот момент не ясен 3) Примените DIFF к текущему изображению. расскажите, пожалуйста, подробно, как применить DIFF к нынешнему изображению? Вы можете перейти к любому коду или статье. большое спасибо. - person Thomas; 30.11.2012
comment
Я никогда раньше не использовал эту библиотеку. Можете ли вы, пожалуйста, дать мне образец кода для этой библиотеки, который я могу использовать для создания разницы (DIFF) двух последовательных изображений и применения DIFF к текущему изображению, то есть IMG2 = DIFF + IMG1. Благодарность - person Thomas; 30.11.2012
comment
У Emgu на самом деле отличная документация. Вы можете найти введение и некоторые основные примеры в Wiki. Этого должно быть достаточно для начала. - person Peopleware; 30.11.2012
comment
Если я использую эту библиотеку, то будет быстрее получить изображение diff, а затем применить DIFF к текущему изображению, что означает IMG2 = DIFF + IMG1. - person Thomas; 30.11.2012
comment
Любые подсказки к моему алгоритму: stackoverflow.com/questions/39690323/? Будет ли правильно использовать его и просто добавить сжатие для отправляемого изображения? Если я знаю, что сжатие будет эффективным, если изображение будет черно-белым, но я думаю, что такое XORing не гарантирует, что - person Michał Ziobro; 25.09.2016
comment
Абсолютная разница не будет работать, поскольку разница в пикселях может давать отрицательные значения, которые будут насыщены до 0. Таким образом, реконструкция будет невозможна. - person thepirat000; 26.09.2016
comment
отрицательные значения? есть abs (), поэтому | a-b | всегда дает положительный | 10-250 | равно 240. Но при их сложении должна быть проверена, больше ли сумма 255, производите вычитание, а не сумму. Но я не знаю, не лучше ли jus XOR с обеих сторон, я проверю это сегодня и дам несколько команд по этому поводу. - person Michał Ziobro; 27.09.2016

Я знаю, что очень поздно отвечаю, но я нашел этот вопрос сегодня

Я провел некоторый анализ различия изображений, но код был написан для java. Пожалуйста, ознакомьтесь с приведенной ниже ссылкой, которая может вам помочь.

Как найти прямоугольник разницы между двумя изображениями < / а>

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

Ваше здоровье !

person Nandhan    schedule 21.11.2013

Что касается моего подхода, я не уверен, что он будет полезен, я бы хотел, чтобы кто-нибудь намекнул, что я двигаюсь в правильном направлении.

Я рассматриваю потоковую передачу с рабочего стола на мобильный телефон. Я бы использовал модель сервер-клиент с сетевыми TCP-сокетами. Считаю такой паттерн (протокол).

СЕРВЕР:

0)

ИЗОБРАЖЕНИЕ ЭКРАНА - представлено как unsigned char *rgba_array IMAGE_SIZE -> ширина, высота

1)

Отправьте клиенту размер изображения ширину, высоту.

2)

init rgba_array с длиной ‹= шириной x высотой x 4 байта (32-битные изображения) и обнулением всего массива.

0000 0000 0000 0000 0000 0000 0000 0000 (пример пикселя - 32 бита)

3)

если у меня есть новое изображение экрана (снимок экрана? или другой способ), я конвертирую его в unsigned char *new_rgba_array, а затем выполняю операцию XOR:

rgba_array XOR new_rgba_array => diff_rgba_array 

4)

чем я только отправляю клиенту это diff_rgba_array СЖАТЫЕ? JPEG?

5) вернитесь к пункту 3) на стороне сервера.

КЛИЕНТ:

0)

получить ширину и высоту -> init rgba_array с длиной ‹= ширина * высота * 4 и обнулить его

1)

получить diff_rgba_array, который представляет изменения по сравнению с предыдущим изображением, и ДЕКОМПРЕССИРОВАТЬ его? JPEG?

0011 1010 0110 0111 1110 0000 0100 0000 (пример разницы пикселей)

0 - бит означает БЕЗ ИЗМЕНЕНИЙ

1 - бит означает ИЗМЕНИТЬ противоположное значение.

2)

применить изменения, полученные от сервера в diff_rgba_array, к rgba_array на стороне клиента. Думаю, мне следует сделать следующее XORing. Нравится

  10011101   10010101

  00001111   11111111 (XOR) 

= 10010010   01101010 

3)

вернитесь к пункту 1) на стороне клиента

person Michał Ziobro    schedule 25.09.2016