0

Я пытаюсь реализовать алгоритм уменьшения эффекта «красных глаз» с помощью SDK Nokia Imaging. Я wroten контроля, чтобы забрать глазные круги, так что я не нужна фаза определения сегментации/лиц (у меня есть список точек в пределах окружности) - Я реализовал это следующим образом:Уменьшение эффекта «красных глаз» с помощью изображений nokia imaging SDK

protected override void OnProcess(PixelRegion sourcePixelRegion, PixelRegion targetPixelRegion) 
    { 
     int currentRow = 0; 

     targetPixelRegion.ForEachRow((index, width, position) => 
     { 
      for (int x = 0; x < width; ++x) 
      { 
       uint currentPixelColor = sourcePixelRegion.ImagePixels[index + x]; 

       if (_selectedRegionProvider.IsPointInSelectedRegion(position.X + x, position.Y + currentRow)) 
       { 
        uint alphaChannel = (currentPixelColor & AlphaBitMask) >> 24; 
        uint redChannel = (currentPixelColor & RedBitMask) >> 16; 
        uint greenChannel = (currentPixelColor & GreenBitMask) >> 8; 
        uint blueChannel = (currentPixelColor & BlueBitMask); 

        float greenBlueChannelAvg = (greenChannel + blueChannel)/2.0f; 

        float redIntensity = (float) (redChannel/greenBlueChannelAvg); 
        if (redIntensity > 0.5) 
         redChannel = Math.Min(255, (uint)((greenChannel+blueChannel)/2.0)); 

        currentPixelColor = (alphaChannel << 24) | (redChannel << 16) | (greenChannel << 8) | blueChannel; 
       } 

       targetPixelRegion.ImagePixels[index + x] = currentPixelColor; 
      } 

      currentRow++; 
     }); 
    } 

где AlphaBitMask = 0xFF000000, RedBitMask = 0x00FF0000, GreenBitMask = 0x0000FF00, BlueBitMask = 0x000000FF

Однако я получаю странные результаты:

Results in left circle

Вопрос в том, использует ли Nokia Imaging SDK какое-то альфа-смешивание? Что мне делать с альфа-каналом? Еще один важный вопрос - кто-нибудь имел дело с CustomFilterBase? Как я могу обработать только список точек (поэтому я мог бы использовать _selectedRegionProvider.GetAllSelectedPoints(), который возвращает IEnumerable of Point), потому что из того, что я видел, OnProcess разделен на несколько частей (поэтому я не могу получить доступ ко всем пикселям в одном OnProcess).

+1

Просто прикосновение к фильтрам CustomFilterBase: (Custom) основано на использовании плитки, поэтому вы правы, в каждом OnProcess у вас есть только доступ к подразделу изображения. Вы все равно можете использовать настраиваемый фильтр и обрабатывать только те пиксели, к которым у вас есть доступ прямо сейчас (пересекаются). Или вы можете использовать собственный эффект (CustomEffectBase), который даст вам доступ ко всем пикселям одновременно, но, конечно, для этого потребуется также больший буфер, поэтому потребление памяти может быть выше. –

+1

Пройдите альфа-канал, не меняйте его. Кроме того, да, ваш OnProcess будет вызываться один раз на один фрагмент изображения. Возможно, вам стоит взглянуть на использование CustomEffectBase. Фильтры ориентированы на плитки, а эффекты - растровые. Если вы выберете редактирование на месте в конструкторе вашего настраиваемого эффекта, вы сможете обрабатывать только интересующие вас пиксели и не перегибать остальные. –

+0

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

ответ

2

Хорошие новости! В недавно выпущенном Lumia Imaging SDK 2.0 есть RedEyeRemovalFilter. Вы можете выполнить обновление через NuGet и посетить http://dev.windows.com/en-us/featured/lumia для получения дополнительной информации.

Обратите внимание, что документация на MSDN в настоящий момент полностью нарушена и не полностью обновлена. Надеюсь, это скоро будет исправлено.

Для справочных документов файл chm в пакете NuGet является текущим и чистым.

1

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

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