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);
|