7

vImageConvert_RGB888toPlanar8Accelerate.framework からandを使用vImageConvert_Planar8toRGB888して RGB24 を BGR24 に変換しますが、変換する必要があるデータが 3M や 4M など非常に大きい場合、これに費やす時間は約 10ms です。それで、誰かが十分に速いアイデアを知っていますか?.私のコードは次のようになります:

- (void)transformRGBToBGR:(const UInt8 *)pict{
rgb.data = (void *)pict;

vImage_Error error = vImageConvert_RGB888toPlanar8(&rgb,&red,&green,&blue,kvImageNoFlags);
if (error != kvImageNoError) {
    NSLog(@"vImageConvert_RGB888toARGB8888 error");
}

error = vImageConvert_Planar8toRGB888(&blue,&green,&red,&bgr,kvImageNoFlags);
if (error != kvImageNoError) {
    NSLog(@"vImagePermuteChannels_ARGB8888 error");
}

free((void *)pict);
}
4

2 に答える 2

8

RGB888ToPlanar8 呼び出しを使用して、データを分散させてから、もう一度収集します。これは非常に非常に悪いです。33% のメモリ オーバーヘッドが許容できる場合は、RGBA 形式を使用して、B/R バイトをインプレースで並べ替えてみてください。

33% 節約したい場合は、次の方法をお勧めします。すべてのピクセルを繰り返しますが、4 バイトの倍数だけを読み取ります (lcm(3,4) は 12 なので、つまり 3 dwords です)。

uint8_t* src_image;
uint8_t* dst_image;

uint32_t* src = (uint32_t*)src_image;
uint32_t* dst = (uint32_t*)dst_image;

uint32_t v1, v2, v3;
uint32_t nv1, nv2, nv3;
for(int i = 0 ; i < num_pixels / 12 ; i++)
{
     // read 12 bytes
     v1 = *src++;
     v2 = *src++;
     v3 = *src++;
     // shuffle bits in the pixels
     // [R1 G1 B1 R2 | G2 B2 R3 G3 | B3 R4 G4 B4]
     nv1 = // [B1 G1 R1 B2]
      ((v1 >> 8) & 0xFF) | (v1 & 0x00FF0000) | ((v1 >> 16) & 0xFF) | ((v2 >> 24) & 0xFF);
     nv2 = // [G2 R2 B3 G3]
       ...
     nv3 = // [R3 B4 G4 R4]
       ...
     // write 12 bytes
     *dst++ = nv1;
     *dst++ = nv2;
     *dst++ = nv3;
}

NEON 組み込み関数を使用すると、さらに良い結果が得られます。

ARM の Web サイトのこのリンクを参照して、24 ビット スワッピングがどのように行われるかを確認してください。

BGR から RGB への変換は、次のようにインプレースで実行できます。

void neon_asm_convert_BGR_TO_RGB(uint8_t* img, int numPixels24)
{
    // numPixels is divided by 24
    __asm__ volatile(
        "0:                \n"
        "# load 3 64-bit regs with interleave: \n"
        "vld3.8      {d0,d1,d2}, [%0]   \n"
        "# swap d0 and d2 - R and B\n"
        "vswp d0, d2   \n"
        "# store 3 64-bit regs: \n"
        "vst3.8      {d0,d1,d2}, [%0]!      \n"
        "subs        %1, %1, #1       \n"
        "bne         0b            \n"
        :
        : "r"(img), "r"(numPixels24)
        : "r4", "r5"
     );
}
于 2012-07-27T08:41:06.627 に答える