Обработка изображений iPhone с помощью Accelerate Framework и vDSP

ОБНОВЛЕНИЕ: пожалуйста, посмотрите дополнительный вопрос ниже с дополнительным кодом;

Я пытаюсь закодировать категорию для размытия изображения. Моя отправная точка - пример Джеффа Ламарша здесь . Хотя это (после исправлений, предложенных другими) работает нормально, двумерная свертка с 3x3 ядро; одинарная точность.

Идеально - у меня есть подходящая матрица фильтров, и у меня есть изображение ... но здесь я в тупике.

vDSP_f3x3 предполагает, что данные изображения (float *), но мое изображение взято из;

srcData = (unsigned char *)CGBitmapContextGetData (context);

, а контекст поступает из CGBitmapContextCreate с kCGImageAlphaPremultipliedFirst, так что мой srcData действительно ARGB с 8 битами на компонент.

Я подозреваю, что мне действительно нужен контекст с компонентами с плавающей запятой, но согласно документации Quartz здесь , kCGBitMapFloatComponents доступен только в Mac OS, но не в iOS: - (

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

Может, у меня неправильный подход?

Кто-нибудь может дать мне несколько советов по обработке изображений на iphone с использованием vDSP ? Документация, которую я могу найти, очень ориентирована на справочные материалы и не очень удобна для новичков, когда дело доходит до такого рода вещей.

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

РЕДАКТИРОВАТЬ:

Спасибо @Jason. Я сделал это, и это почти работает, но теперь моя проблема в том, что, хотя изображение действительно размывается, при каждом вызове оно сдвигается влево на 1 пиксель. Также кажется, что изображение становится черно-белым, но это может быть что-то еще.

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

CGImageRef CreateCGImageByBlurringImage(CGImageRef inImage, NSUInteger pixelRadius, NSUInteger gaussFactor)
{
unsigned char *srcData, *finalData;

CGContextRef context = CreateARGBBitmapContext(inImage);
if (context == NULL) 
    return NULL;

size_t width = CGBitmapContextGetWidth(context);
size_t height = CGBitmapContextGetHeight(context);
size_t bpr = CGBitmapContextGetBytesPerRow(context);

int componentsPerPixel = 4; // ARGB

CGRect rect = {{0,0},{width,height}}; 
CGContextDrawImage(context, rect, inImage); 

// Now we can get a pointer to the image data associated with the bitmap
// context.

srcData = (unsigned char *)CGBitmapContextGetData (context);

if (srcData != NULL)
{

    size_t dataSize = bpr * height;
    finalData = malloc(dataSize);
    memcpy(finalData, srcData, dataSize);

    //Generate Gaussian kernel

    float *kernel;  

    // Limit the pixelRadius

    pixelRadius = MIN(MAX(1,pixelRadius), 248);
    int kernelSize = pixelRadius * 2 + 1;

    kernel = malloc(kernelSize * sizeof *kernel);

    int gauss_sum =0;

    for (int i = 0; i < pixelRadius; i++)
    {
        kernel[i] = 1 + (gaussFactor*i);
        kernel[kernelSize - (i + 1)] = 1 + (gaussFactor * i);
        gauss_sum += (kernel[i] + kernel[kernelSize - (i + 1)]);
    }

    kernel[(kernelSize - 1)/2] = 1 + (gaussFactor*pixelRadius);

    gauss_sum += kernel[(kernelSize-1)/2];

    // Scale the kernel

    for (int i=0; i

Я должен добавить это, если я закомментирую строку vDSP_conv и изменю следующую строку на;

       vDSP_vfixu8(srcAsFloat, 1, finalData, 1, width*height*componentsPerPixel);

Затем, как ожидалось , мой результат - клон оригинального источника. По цвету так и не сместился влево. Это подразумевает, что свертка идет не так, но я не вижу, где: - (

МЫСЛЬ: На самом деле, думая об этом, мне кажется, что свертка должна знать, что входные пиксели находятся в ARGB формат, так как в противном случае свертка будет умножать значения вместе без знания их значения (то есть будет многократно R * B и т. д.). Это объясняет, почему я получаю черно-белый результат, я думаю, но не сдвиг. Я думаю, что здесь может быть что-то большее, чем моя наивная версия ...

ЗАКЛЮЧИТЕЛЬНАЯ МЫСЛЬ: Я думаю, что сдвиг влево - естественный результат фильтра, и мне нужно посмотреть на размеры изображения и, возможно, дополнить его ... так что я думаю, что код действительно работает нормально, учитывая то, что я его скармливал.

8
задан Roger 9 May 2011 в 19:30
поделиться