color.cpp.DIFF

Martin Beckett, 2012-05-11 10:46 pm

Download (10.8 kB)

 
"b/E:\\OpenCV2.4\\opencv\\modules\\imgproc\\src\\color-RGBA.cpp"
1879 1879
        return (int)(bayer - (bayer_end - width));
1880 1880
    }
1881 1881
    
1882
	// MGB RGBA support
1883
	// THIS doesn't 'quite' work - need some help!
1884
	 int bayer2RGBA(const uchar* bayer, int bayer_step, uchar* dst, int width, int blue) const
1885
    {
1886
		
1887
        if( !use_simd )
1888
            return 0;
1889
        /*
1890
         B G B G | B G B G | B G B G | B G B G
1891
         G R G R | G R G R | G R G R | G R G R
1892
         B G B G | B G B G | B G B G | B G B G
1893
         */
1894
        __m128i delta1 = _mm_set1_epi16(1), delta2 = _mm_set1_epi16(2);
1895
        __m128i mask = _mm_set1_epi16(blue < 0 ? -1 : 0);
1896
		//__m128i z = _mm_setzero_si128();        						
1897
		__m128i z = _mm_set_epi32(0xffffffff,0xffffffff,0xffffffff,0xffffffff);
1898

  
1899
		__m128i masklo = _mm_set1_epi16(0x00ff);
1900
        const uchar* bayer_end = bayer + width;
1901
                 
1902
		for( ; bayer <= bayer_end - 18; bayer += 14, dst += 56 )
1903
        {
1904
            __m128i r0 = _mm_loadu_si128((const __m128i*)bayer);
1905
            __m128i r1 = _mm_loadu_si128((const __m128i*)(bayer+bayer_step));
1906
            __m128i r2 = _mm_loadu_si128((const __m128i*)(bayer+bayer_step*2));
1907
            
1908
            __m128i b1 = _mm_add_epi16(_mm_and_si128(r0, masklo), _mm_and_si128(r2, masklo));
1909
            __m128i b0 = _mm_add_epi16(b1, _mm_srli_si128(b1, 2));
1910
            b1 = _mm_srli_si128(b1, 2);
1911
            b1 = _mm_srli_epi16(_mm_add_epi16(b1, delta1), 1);
1912
            b0 = _mm_srli_epi16(_mm_add_epi16(b0, delta2), 2);
1913
            b0 = _mm_packus_epi16(b0, b1);
1914
            
1915
            __m128i g0 = _mm_add_epi16(_mm_srli_epi16(r0, 8), _mm_srli_epi16(r2, 8));
1916
            __m128i g1 = _mm_and_si128(r1, masklo);
1917
            g0 = _mm_add_epi16(g0, _mm_add_epi16(g1, _mm_srli_si128(g1, 2)));
1918
            g1 = _mm_srli_si128(g1, 2);
1919
            g0 = _mm_srli_epi16(_mm_add_epi16(g0, delta2), 2);
1920
            g0 = _mm_packus_epi16(g0, g1);
1921
            
1922
            r0 = _mm_srli_epi16(r1, 8);
1923
            r1 = _mm_add_epi16(r0, _mm_srli_si128(r0, 2));
1924
            r1 = _mm_srli_epi16(_mm_add_epi16(r1, delta1), 1);
1925
            r0 = _mm_packus_epi16(r0, r1);
1926
            
1927
            b1 = _mm_and_si128(_mm_xor_si128(b0, r0), mask);
1928
            b0 = _mm_xor_si128(b0, b1);
1929
            r0 = _mm_xor_si128(r0, b1);
1930
            
1931
            // b1 g1 b1 g1 ...
1932
            b1 = _mm_unpackhi_epi8(b0, g0);
1933
            // b0 g0 b2 g2 b4 g4 ....
1934
            b0 = _mm_unpacklo_epi8(b0, g0);
1935
            
1936
            // r1 0 r3 0 ...
1937
            r1 = _mm_unpackhi_epi8(r0, z);
1938
            // r0 0 r2 0 r4 0 ...
1939
            r0 = _mm_unpacklo_epi8(r0, z);
1940
            
1941
            // 0 b0 g0 r0 0 b2 g2 r2 0 ...
1942
            g0 = _mm_slli_si128(_mm_unpacklo_epi16(b0, r0), 1);
1943
            // 0 b8 g8 r8 0 b10 g10 r10 0 ...
1944
            g1 = _mm_slli_si128(_mm_unpackhi_epi16(b0, r0), 1);
1945
            
1946
            // b1 g1 r1 0 b3 g3 r3 ....
1947
            r0 = _mm_unpacklo_epi16(b1, r1);
1948
            // b9 g9 r9 0 ...
1949
            r1 = _mm_unpackhi_epi16(b1, r1);
1950
            
1951
            b0 = _mm_srli_si128(_mm_unpacklo_epi32(g0, r0), 1);
1952
            b1 = _mm_srli_si128(_mm_unpackhi_epi32(g0, r0), 1);
1953
            
1954
            _mm_storel_epi64((__m128i*)(dst-0), b0);
1955
            _mm_storel_epi64((__m128i*)(dst-0+8*1), _mm_srli_si128(b0, 8));
1956
            _mm_storel_epi64((__m128i*)(dst-0+8*2), b1);
1957
            _mm_storel_epi64((__m128i*)(dst-0+8*3), _mm_srli_si128(b1, 8));
1958

  
1959
            g0 = _mm_srli_si128(_mm_unpacklo_epi32(g1, r1), 1);
1960
            g1 = _mm_srli_si128(_mm_unpackhi_epi32(g1, r1), 1);
1961
            
1962
            _mm_storel_epi64((__m128i*)(dst-0+8*4), g0);
1963
            _mm_storel_epi64((__m128i*)(dst-0+8*5), _mm_srli_si128(g0, 8));            
1964
            _mm_storel_epi64((__m128i*)(dst-0+8*6), g1);
1965

  
1966
        }
1967
        // end MGB RGBA support
1968
        return (int)(bayer - (bayer_end - width));
1969
    }
1882 1970
    bool use_simd;
1883 1971
};
1884 1972
#else
......
2110 2198
        }
2111 2199
}
2112 2200

  
2201
// MGB RGBA support
2202
template<typename T, class SIMDInterpolator>    
2203
static void Bayer2RGBA_( const Mat& srcmat, Mat& dstmat, int code )
2204
{
2205
    SIMDInterpolator vecOp;
2206
	
2207
    const T* bayer0 = (const T*)srcmat.data;
2208
    int bayer_step = (int)(srcmat.step/sizeof(T));
2209
    T* dst0 = (T*)dstmat.data;
2210
    int dst_step = (int)(dstmat.step/sizeof(T));
2211
    Size size = srcmat.size();
2212
    int blue = code == CV_BayerBG2BGRA || code == CV_BayerGB2BGRA ? -1 : 1;
2213
    int start_with_green = code == CV_BayerGB2BGRA || code == CV_BayerGR2BGRA;
2113 2214
    
2215
	T alpha = 0xff;
2216

  
2217
    dst0 += dst_step + 4 + 1;
2218
    size.height -= 2;
2219
    size.width -= 2;
2220
        
2221
    for( ; size.height-- > 0; bayer0 += bayer_step, dst0 += dst_step )
2222
    {
2223
        int t0, t1;
2224
        const T* bayer = bayer0;
2225
        T* dst = dst0;
2226
        const T* bayer_end = bayer + size.width;
2227
        
2228
        if( size.width <= 0 )
2229
        {
2230
            dst[-4] = dst[-3] = dst[-2] = dst[size.width*4-1] =
2231
            dst[size.width*4] = dst[size.width*4+1] = 0;
2232
            continue;
2233
        }
2234
        
2235
        if( start_with_green )
2236
        {
2237
            t0 = (bayer[1] + bayer[bayer_step*2+1] + 1) >> 1;
2238
            t1 = (bayer[bayer_step] + bayer[bayer_step+2] + 1) >> 1;
2239
            dst[-blue] = (T)t0;
2240
            dst[0] = bayer[bayer_step+1];
2241
            dst[blue] = (T)t1;
2242
            bayer++;
2243
            dst += 4;
2244
        }
2245
        
2246
		// Can't make the SIMD work quite correctly
2247
        //int delta = vecOp.bayer2RGBA(bayer, bayer_step, dst, size.width, blue);
2248
		int delta = 0;
2249
        bayer += delta;
2250
        dst += delta*4;
2251
                
2252
        if( blue > 0 )
2253
        {
2254
            for( ; bayer <= bayer_end - 2; bayer += 2, dst += 8 )
2255
            {
2256
                t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] +
2257
                      bayer[bayer_step*2+2] + 2) >> 2;
2258
                t1 = (bayer[1] + bayer[bayer_step] +
2259
                      bayer[bayer_step+2] + bayer[bayer_step*2+1]+2) >> 2;
2260
                dst[-1] = (T)t0;
2261
                dst[0] = (T)t1;
2262
                dst[1] = bayer[bayer_step+1];
2263
                				
2264
				dst[2] = alpha;
2265

  
2266
                t0 = (bayer[2] + bayer[bayer_step*2+2] + 1) >> 1;
2267
                t1 = (bayer[bayer_step+1] + bayer[bayer_step+3] + 1) >> 1;
2268
                dst[3] = (T)t0;
2269
                dst[4] = bayer[bayer_step+2];
2270
                dst[5] = (T)t1;
2271
				
2272
				dst[6] = alpha;
2273
            }
2274
        }
2275
        else
2276
        {
2277
            for( ; bayer <= bayer_end - 2; bayer += 2, dst += 8 )
2278
            {
2279
                t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] +
2280
                      bayer[bayer_step*2+2] + 2) >> 2;
2281
                t1 = (bayer[1] + bayer[bayer_step] +
2282
                      bayer[bayer_step+2] + bayer[bayer_step*2+1]+2) >> 2;
2283
				
2284
				dst[2] = alpha;
2285
                
2286
				dst[1] = (T)t0;
2287
                dst[0] = (T)t1;
2288
                dst[-1] = bayer[bayer_step+1];
2289
                
2290

  
2291
                t0 = (bayer[2] + bayer[bayer_step*2+2] + 1) >> 1;
2292
                t1 = (bayer[bayer_step+1] + bayer[bayer_step+3] + 1) >> 1;				
2293
				dst[6] = alpha; 
2294

  
2295
                dst[5] = (T)t0;
2296
                dst[4] = bayer[bayer_step+2];
2297
                dst[3] = (T)t1;
2298
            }
2299
        }
2300
        
2301
        if( bayer < bayer_end )
2302
        {
2303
            t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] +
2304
                  bayer[bayer_step*2+2] + 2) >> 2;
2305
            t1 = (bayer[1] + bayer[bayer_step] +
2306
                  bayer[bayer_step+2] + bayer[bayer_step*2+1]+2) >> 2;
2307
            dst[-blue] = (T)t0;
2308
            dst[0] = (T)t1;
2309
            dst[blue] = bayer[bayer_step+1];
2310
            bayer++;
2311
            dst += 4;
2312
        }
2313
        
2314
		
2315
        dst0[-4] = dst0[-1];
2316
        dst0[-3] = dst0[0];
2317
        dst0[-2] = dst0[1];
2318
        dst0[size.width*4-1] = dst0[size.width*4-4];
2319
        dst0[size.width*4] = dst0[size.width*4-3];
2320
        dst0[size.width*4+1] = dst0[size.width*4-2];
2321
        
2322
        blue = -blue;
2323
        start_with_green = !start_with_green;
2324
    }
2325
    
2326
	
2327
    size = dstmat.size();
2328
    dst0 = (T*)dstmat.data;
2329
    if( size.height > 2 )
2330
        for( int i = 0; i < size.width*4; i++ )
2331
        {
2332
            dst0[i] = dst0[i + dst_step];
2333
            dst0[i + (size.height-1)*dst_step] = dst0[i + (size.height-2)*dst_step];
2334
        }
2335
    else
2336
        for( int i = 0; i < size.width*4; i++ )
2337
        {
2338
            dst0[i] = dst0[i + (size.height-1)*dst_step] = 0;
2339
        }
2340
	
2341
}
2342
// end MGB    
2114 2343
/////////////////// Demosaicing using Variable Number of Gradients ///////////////////////
2115 2344
    
2116 2345
static void Bayer2RGB_VNG_8u( const Mat& srcmat, Mat& dstmat, int code )
......
3474 3703
            else
3475 3704
                CV_Error(CV_StsUnsupportedFormat, "Bayer->Gray demosaicing only supports 8u and 16u types");
3476 3705
            break;
3477
            
3478
        case CV_BayerBG2BGR: case CV_BayerGB2BGR: case CV_BayerRG2BGR: case CV_BayerGR2BGR:
3706

  
3707
		// MGB RGBA support  		
3708
		case CV_BayerBG2BGRA: case CV_BayerGB2BGRA: case CV_BayerRG2BGRA: case CV_BayerGR2BGRA:
3709
            if(dcn <= 0) dcn = 4;   
3710
			CV_Assert( scn == 1 && dcn == 4 );
3711

  
3712
			_dst.create(sz, CV_MAKETYPE(depth, dcn));
3713
            dst = _dst.getMat();
3714

  
3715
			if  ( code == CV_BayerBG2BGRA || code == CV_BayerGB2BGRA ||
3716
						code == CV_BayerRG2BGRA || code == CV_BayerGR2BGRA )
3717
			{
3718
				
3719
				if( depth == CV_8U )
3720
				        Bayer2RGBA_<uchar, SIMDBayerInterpolator_8u>(src, dst, code);                                
3721
                else
3722
                    CV_Error(CV_StsUnsupportedFormat, "Bayer->RGBA demosaicing only supports 8u types");
3723
			}
3724
			break;
3725

  
3726
        case CV_BayerBG2BGR: case CV_BayerGB2BGR: case CV_BayerRG2BGR: case CV_BayerGR2BGR:	    
3479 3727
        case CV_BayerBG2BGR_VNG: case CV_BayerGB2BGR_VNG: case CV_BayerRG2BGR_VNG: case CV_BayerGR2BGR_VNG:
3480 3728
            if(dcn <= 0) dcn = 3;
3481 3729
            CV_Assert( scn == 1 && dcn == 3 );
3482
            
3730

  
3483 3731
            _dst.create(sz, CV_MAKETYPE(depth, dcn));
3484 3732
            dst = _dst.getMat();
3485 3733
            
......
3492 3740
                    Bayer2RGB_<ushort, SIMDBayerStubInterpolator_<ushort> >(src, dst, code);
3493 3741
                else
3494 3742
                    CV_Error(CV_StsUnsupportedFormat, "Bayer->RGB demosaicing only supports 8u and 16u types");
3495
            }
3496
            else
3743
			}
3744
			else
3497 3745
            {
3498 3746
                CV_Assert( depth == CV_8U );
3499 3747
                Bayer2RGB_VNG_8u(src, dst, code);