Commit b8b13ccd authored by Ilya Lavrenov's avatar Ilya Lavrenov

parallel version of Bayer2Gray

parent ce5e9a71
...@@ -210,95 +210,141 @@ public: ...@@ -210,95 +210,141 @@ public:
typedef SIMDBayerStubInterpolator_<uchar> SIMDBayerInterpolator_8u; typedef SIMDBayerStubInterpolator_<uchar> SIMDBayerInterpolator_8u;
#endif #endif
template<typename T, class SIMDInterpolator> template<typename T, class SIMDInterpolator>
static void Bayer2Gray_( const Mat& srcmat, Mat& dstmat, int code ) class Bayer2Gray_Invoker :
public ParallelLoopBody
{ {
SIMDInterpolator vecOp; public:
const int R2Y = 4899; Bayer2Gray_Invoker(const Mat& _srcmat, Mat& _dstmat, int _start_with_green, bool _brow,
const int G2Y = 9617; const Size& _size, int _bcoeff, int _rcoeff) :
const int B2Y = 1868; ParallelLoopBody(), srcmat(_srcmat), dstmat(_dstmat), Start_with_green(_start_with_green),
const int SHIFT = 14; Brow(_brow), size(_size), Bcoeff(_bcoeff), Rcoeff(_rcoeff)
const T* bayer0 = (const T*)srcmat.data;
int bayer_step = (int)(srcmat.step/sizeof(T));
T* dst0 = (T*)dstmat.data;
int dst_step = (int)(dstmat.step/sizeof(T));
Size size = srcmat.size();
int bcoeff = B2Y, rcoeff = R2Y;
int start_with_green = code == CV_BayerGB2GRAY || code == CV_BayerGR2GRAY;
bool brow = true;
if( code != CV_BayerBG2GRAY && code != CV_BayerGB2GRAY )
{ {
brow = false;
std::swap(bcoeff, rcoeff);
} }
dst0 += dst_step + 1; virtual void operator ()(const Range& range) const
size.height -= 2;
size.width -= 2;
for( ; size.height-- > 0; bayer0 += bayer_step, dst0 += dst_step )
{ {
unsigned t0, t1, t2; SIMDInterpolator vecOp;
const T* bayer = bayer0; const int G2Y = 9617;
T* dst = dst0; const int SHIFT = 14;
const T* bayer_end = bayer + size.width;
const T* bayer0 = (const T*)srcmat.data;
int bayer_step = (int)(srcmat.step/sizeof(T));
T* dst0 = (T*)dstmat.data;
int dst_step = (int)(dstmat.step/sizeof(T));
int bcoeff = Bcoeff, rcoeff = Rcoeff;
int start_with_green = Start_with_green;
bool brow = Brow;
dst0 += dst_step + 1;
if( size.width <= 0 ) if (range.start % 2)
{ {
dst[-1] = dst[size.width] = 0; brow = !brow;
continue; std::swap(bcoeff, rcoeff);
start_with_green = !start_with_green;
} }
if( start_with_green ) bayer0 += range.start * bayer_step;
dst0 += range.start * dst_step;
for(int i = range.start ; i < range.end; ++i, bayer0 += bayer_step, dst0 += dst_step )
{ {
t0 = (bayer[1] + bayer[bayer_step*2+1])*rcoeff; unsigned t0, t1, t2;
t1 = (bayer[bayer_step] + bayer[bayer_step+2])*bcoeff; const T* bayer = bayer0;
t2 = bayer[bayer_step+1]*(2*G2Y); T* dst = dst0;
const T* bayer_end = bayer + size.width;
dst[0] = (T)CV_DESCALE(t0 + t1 + t2, SHIFT+1); if( size.width <= 0 )
bayer++; {
dst++; dst[-1] = dst[size.width] = 0;
} continue;
}
int delta = vecOp.bayer2Gray(bayer, bayer_step, dst, size.width, bcoeff, G2Y, rcoeff); if( start_with_green )
bayer += delta; {
dst += delta; t0 = (bayer[1] + bayer[bayer_step*2+1])*rcoeff;
t1 = (bayer[bayer_step] + bayer[bayer_step+2])*bcoeff;
t2 = bayer[bayer_step+1]*(2*G2Y);
for( ; bayer <= bayer_end - 2; bayer += 2, dst += 2 ) dst[0] = (T)CV_DESCALE(t0 + t1 + t2, SHIFT+1);
{ bayer++;
t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] + bayer[bayer_step*2+2])*rcoeff; dst++;
t1 = (bayer[1] + bayer[bayer_step] + bayer[bayer_step+2] + bayer[bayer_step*2+1])*G2Y; }
t2 = bayer[bayer_step+1]*(4*bcoeff);
dst[0] = (T)CV_DESCALE(t0 + t1 + t2, SHIFT+2);
t0 = (bayer[2] + bayer[bayer_step*2+2])*rcoeff;
t1 = (bayer[bayer_step+1] + bayer[bayer_step+3])*bcoeff;
t2 = bayer[bayer_step+2]*(2*G2Y);
dst[1] = (T)CV_DESCALE(t0 + t1 + t2, SHIFT+1);
}
if( bayer < bayer_end ) int delta = vecOp.bayer2Gray(bayer, bayer_step, dst, size.width, bcoeff, G2Y, rcoeff);
{ bayer += delta;
t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] + bayer[bayer_step*2+2])*rcoeff; dst += delta;
t1 = (bayer[1] + bayer[bayer_step] + bayer[bayer_step+2] + bayer[bayer_step*2+1])*G2Y;
t2 = bayer[bayer_step+1]*(4*bcoeff); for( ; bayer <= bayer_end - 2; bayer += 2, dst += 2 )
dst[0] = (T)CV_DESCALE(t0 + t1 + t2, SHIFT+2); {
bayer++; t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] + bayer[bayer_step*2+2])*rcoeff;
dst++; t1 = (bayer[1] + bayer[bayer_step] + bayer[bayer_step+2] + bayer[bayer_step*2+1])*G2Y;
t2 = bayer[bayer_step+1]*(4*bcoeff);
dst[0] = (T)CV_DESCALE(t0 + t1 + t2, SHIFT+2);
t0 = (bayer[2] + bayer[bayer_step*2+2])*rcoeff;
t1 = (bayer[bayer_step+1] + bayer[bayer_step+3])*bcoeff;
t2 = bayer[bayer_step+2]*(2*G2Y);
dst[1] = (T)CV_DESCALE(t0 + t1 + t2, SHIFT+1);
}
if( bayer < bayer_end )
{
t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] + bayer[bayer_step*2+2])*rcoeff;
t1 = (bayer[1] + bayer[bayer_step] + bayer[bayer_step+2] + bayer[bayer_step*2+1])*G2Y;
t2 = bayer[bayer_step+1]*(4*bcoeff);
dst[0] = (T)CV_DESCALE(t0 + t1 + t2, SHIFT+2);
bayer++;
dst++;
}
dst0[-1] = dst0[0];
dst0[size.width] = dst0[size.width-1];
brow = !brow;
std::swap(bcoeff, rcoeff);
start_with_green = !start_with_green;
} }
}
private:
const Mat srcmat;
Mat dstmat;
const int Start_with_green;
const bool Brow;
const Size size;
const int Bcoeff, Rcoeff;
};
dst0[-1] = dst0[0]; template<typename T, typename SIMDInterpolator>
dst0[size.width] = dst0[size.width-1]; static void Bayer2Gray_( const Mat& srcmat, Mat& dstmat, int code )
{
const int R2Y = 4899;
const int B2Y = 1868;
brow = !brow; Size size = srcmat.size();
int bcoeff = B2Y, rcoeff = R2Y;
int start_with_green = code == CV_BayerGB2GRAY || code == CV_BayerGR2GRAY;
bool brow = true;
if( code != CV_BayerBG2GRAY && code != CV_BayerGB2GRAY )
{
brow = false;
std::swap(bcoeff, rcoeff); std::swap(bcoeff, rcoeff);
start_with_green = !start_with_green;
} }
size.height -= 2;
size.width -= 2;
Range range(0, size.height);
Bayer2Gray_Invoker<T, SIMDInterpolator> invoker(srcmat, dstmat,
start_with_green, brow, size, bcoeff, rcoeff);
parallel_for_(range, invoker);
size = dstmat.size(); size = dstmat.size();
dst0 = (T*)dstmat.data; T* dst0 = (T*)dstmat.data;
int dst_step = (int)(dstmat.step/sizeof(T));
if( size.height > 2 ) if( size.height > 2 )
for( int i = 0; i < size.width; i++ ) for( int i = 0; i < size.width; i++ )
{ {
...@@ -340,6 +386,7 @@ class Bayer2RGB_Invoker : ...@@ -340,6 +386,7 @@ class Bayer2RGB_Invoker :
{ {
public: public:
Bayer2RGB_Invoker(const Mat& _srcmat, Mat& _dstmat, int _start_with_green, int _blue, const Size& _size) : Bayer2RGB_Invoker(const Mat& _srcmat, Mat& _dstmat, int _start_with_green, int _blue, const Size& _size) :
ParallelLoopBody(),
srcmat(_srcmat), dstmat(_dstmat), Start_with_green(_start_with_green), Blue(_blue), size(_size) srcmat(_srcmat), dstmat(_dstmat), Start_with_green(_start_with_green), Blue(_blue), size(_size)
{ {
print("Bayer2RGB_Invoker()\n"); print("Bayer2RGB_Invoker()\n");
...@@ -349,12 +396,14 @@ public: ...@@ -349,12 +396,14 @@ public:
{ {
SIMDInterpolator vecOp; SIMDInterpolator vecOp;
T alpha = Alpha<T>::value(); T alpha = Alpha<T>::value();
int dcn = dstmat.channels();
int dcn2 = dcn << 1;
const T* bayer0 = (const T*)srcmat.data;
int bayer_step = (int)(srcmat.step/sizeof(T)); int bayer_step = (int)(srcmat.step/sizeof(T));
const T* bayer0 = reinterpret_cast<const T*>(srcmat.data) + bayer_step * range.start;
T* dst0 = (T*)dstmat.data;
int dst_step = (int)(dstmat.step/sizeof(T)); int dst_step = (int)(dstmat.step/sizeof(T));
T* dst0 = reinterpret_cast<T*>(dstmat.data) + (range.start + 1) * dst_step + dcn + 1;
int blue = Blue, start_with_green = Start_with_green; int blue = Blue, start_with_green = Start_with_green;
if (range.start % 2) if (range.start % 2)
...@@ -362,14 +411,6 @@ public: ...@@ -362,14 +411,6 @@ public:
blue = -blue; blue = -blue;
start_with_green = !start_with_green; start_with_green = !start_with_green;
} }
int dcn = dstmat.channels();
dst0 += dst_step + dcn + 1;
int dcn2 = dcn << 1;
dst0 += dst_step * range.start;
bayer0 += bayer_step * range.start;
print(range.start); print(range.start);
for (int i = range.start; i < range.end; bayer0 += bayer_step, dst0 += dst_step, ++i ) for (int i = range.start; i < range.end; bayer0 += bayer_step, dst0 += dst_step, ++i )
...@@ -547,7 +588,7 @@ public: ...@@ -547,7 +588,7 @@ public:
} }
} }
public: private:
const Mat srcmat; const Mat srcmat;
Mat dstmat; Mat dstmat;
int Start_with_green, Blue; int Start_with_green, Blue;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment