2

私は現在、グレースケールNSImageの列と行を合計するコードをCPUで実行しています(つまり、1つのsamplePerPixelのみ)。コードをGPUに移動しようと思いました(可能であれば)。似ているように見えるCoreImageフィルターCIRowAverageCIColumnAverageを見つけました。

カスタムコアイメージフィルターの作成に関するAppleDocsには、次のように記載されています。

コードはピクセルごとに知識を蓄積できないことに注意してください。コードを作成する際の優れた戦略は、実際のカーネルから可能な限り不変の計算を移動し、それをフィルターのObjective-C部分に配置することです。

これは、フィルターカーネルを使用してピクセルの合計を作成できない可能性があることを示唆しています。もしそうなら、上記の関数はどのようにして地域の平均を取得することができますか?

だから私の質問は、ピクセルの合計値を取得するために画像の行または列の合計を実装するための最良の方法は何ですか?CPUに固執する必要がありますか?

4

2 に答える 2

5

Core Imageフィルターは、一連の削減を通じてこの平均化を実行します。チームの元エンジニアは、このGPU Gemsの章(セクション26.2.2「重心の検索」の下)でCIAreaAverageフィルターに対してこれがどのように行われたかを説明しています。

私はここで私の答えを減らすことによる同様の平均化について話します。iOSでこの機能が必要だったので、画像を水平方向と垂直方向の両方で4分の1に縮小するフラグメントシェーダーを作成し、各ステップで平均16ピクセルを1つにするためにピクセル間をサンプリングしました。画像が十分に小さいサイズに縮小されると、残りのピクセルが読み取られ、平均化されて単一の最終値が生成されます。

この種の削減はGPUで実行するのがまだ非常に高速であり、iPhone4では約6ミリ秒で640x480のビデオフレームから平均的な色を抽出することができました。もちろん、より多くの馬力で遊ぶことができます。 Macで。

各ステップで一方向または他の方向にのみ縮小することで、これと同様のアプローチを取ることができます。ピクセル値の合計を取得することに関心がある場合は、GPUで使用されるピクセル形式の精度の制限に注意する必要があります。デフォルトでは、RGBAカラー値は8ビット値として保存されますが、特定のGPUのOpenGL(ES)拡張機能を使用すると、ダイナミックレンジを拡張する16ビットまたは32ビットの浮動小数点テクスチャにレンダリングできます。よくわかりませんが、CoreImageではMacで32ビットのfloatコンポーネントを使用できると思います。

于 2013-01-23T18:24:02.987 に答える
1

CIAreaAverageフィルターのFYI-次のようにコード化されています。

    CGRect inputExtent = [self.inputImage extent];
CIVector *extent = [CIVector vectorWithX:inputExtent.origin.x
                                       Y:inputExtent.origin.y
                                       Z:inputExtent.size.width
                                       W:inputExtent.size.height];
CIImage* inputAverage = [CIFilter filterWithName:@"CIAreaAverage" keysAndValues:@"inputImage", self.inputImage, @"inputExtent", extent, nil].outputImage;

//CIImage* inputAverage = [self.inputImage imageByApplyingFilter:@"CIAreaMinimum" withInputParameters:@{@"inputImage" : inputImage, @"inputExtent" : extent}];
EAGLContext *myEAGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
NSDictionary *options = @{ kCIContextWorkingColorSpace : [NSNull null] };
CIContext *myContext = [CIContext contextWithEAGLContext:myEAGLContext options:options];

size_t rowBytes = 32 ; // ARGB has 4 components
uint8_t byteBuffer[rowBytes]; // Buffer to render into

[myContext render:inputAverage toBitmap:byteBuffer rowBytes:rowBytes bounds:[inputAverage extent] format:kCIFormatRGBA8 colorSpace:nil];

const uint8_t* pixel = &byteBuffer[0];
float red   = pixel[0] / 255.0;
float green = pixel[1] / 255.0;
float blue  = pixel[2] / 255.0;
NSLog(@"%f, %f, %f\n", red, green, blue);

出力は次のようになります。

2015-05-23 15:58:20.935 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196
2015-05-23 15:58:20.981 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196
于 2015-05-23T23:25:42.323 に答える