質問

更新:以下の追加の質問を参照してください。

画像を曖昧にするためのカテゴリをコーディングしようとしています。私の出発点はです ジェフ・ラマルケのサンプルはこちら. 。これ(他の人が提案した修正後)は正常に動作しますが、私の要件には1桁遅すぎます - 3GSでは、まともなぼかしをするのに3秒かかるかもしれません。フル画面のSEC(より速い方が良い)。

彼はパフォーマンスの強化として加速フレームワークを言及しているので、私はこれを見て、特にAppleの文書化によるとVDSP_F3X3を見て過ごしました。

3x3カーネルで2次元の畳み込みを実行して画像をフィルターします。単一の精度。

完璧 - 私は適切なフィルターマトリックスを持っていて、画像があります...しかし、これは私が困惑する場所です。

vdsp_f3x3は画像データが(float *)であると想定していますが、私の画像はからです。

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

そして、コンテキストはkcgimagealphapremultipiredfirstを使用したcgbitmapcontextcreateから来ているため、私のsrcdataはコンポーネントあたり8ビットの実際にArgbです。

私が本当に必要なのはフロートコンポーネントのコンテキストだと思いますが、 ここのクォーツのドキュメントによると, 、kcgbitmapfloatcomponentsは、iOSではなくMac OSでのみ利用できます:-(

VDSP_F3X3が必要とするフロートコンポーネントに持っている整数コンポーネントを変換するAccelerate Frameworkを使用して、非常に高速な方法はありますか?私は自分でそれをすることができましたが、それをする頃には、畳み込み、そして戻って戻るまでに、私は私が行くように畳み込むかもしれないので、今よりも遅くなったと思います。

多分私には間違ったアプローチがありますか?

VDSPを使用してiPhoneで画像処理を行ったためのヒントはありますか?私が見つけることができるドキュメントは、この種のことに関しては、非常に参照指向であり、初心者に優しいものではありません。

誰かが本当に速いぼやけた(そして高品質で、解像度を減らして、そして私が見たものやズボンのように見えます)のリファレンスを持っている場合、それはファブになります!

編集:

ありがとう@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<kernelSize; ++i) {
        kernel[i] = kernel[i]/gauss_sum;
    }

    float * srcAsFloat,* resultAsFloat;

    srcAsFloat = malloc(width*height*sizeof(float)*componentsPerPixel);
    resultAsFloat = malloc(width*height*sizeof(float)*componentsPerPixel);

   // Convert uint source ARGB to floats

    vDSP_vfltu8(srcData,1,srcAsFloat,1,width*height*componentsPerPixel);

    // Convolve (hence the -1) with the kernel

    vDSP_conv(srcAsFloat, 1, &kernel[kernelSize-1],-1, resultAsFloat, 1, width*height*componentsPerPixel, kernelSize);

    // Copy the floats back to ints

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

    free(resultAsFloat);
    free(srcAsFloat);

}

size_t bitmapByteCount = bpr * height;

CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, finalData, bitmapByteCount, &providerRelease);

CGImageRef cgImage = CGImageCreate(width, height, CGBitmapContextGetBitsPerComponent(context),
                                   CGBitmapContextGetBitsPerPixel(context), CGBitmapContextGetBytesPerRow(context), CGBitmapContextGetColorSpace(context), CGBitmapContextGetBitmapInfo(context), 
                                   dataProvider, NULL, true, kCGRenderingIntentDefault);

CGDataProviderRelease(dataProvider);
CGContextRelease(context); 


return cgImage;
}

VDSP_CONV行にコメントして、次の行を変更する場合は追加する必要があります。

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

予想通り、私の結果は元のソースのクローンです。色があり、左にシフトされていません。これは私に、それが間違っているのは畳み込みであることを意味しますが、どこでわかりません:-(

考え:実際にこれについて考えて、コンバルブは入力ピクセルがArgb形式であることを知る必要があるように思えます。 。これは、私がB&Wの結果を得る理由を説明するでしょうが、シフトではありません。繰り返しますが、ここに私の素朴なバージョンよりもそれ以上のものが必要かもしれないと思います...

最終的な考え:左シフトはフィルターの自然な結果であると思います。画像の寸法を見て、おそらくそれをパッドアウトする必要があります...だから、私がそれを与えたものを考えると、コードは実際にうまく機能していると思います。

正しい解決策はありません

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top