mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 15:23:05 +04:00
Add ocl's good features to track implementation.
Additional notes with this commit: 1. Add cornerHarris_dxdy and cornerMinEigenVal_dxdy to get the interim dx and dy output of Sobel operator; 2. Add minMax_buf to allow user to reuse buffers in minMax; 3. Fix an error when either min or max pointer fed into minMax is NULL; 4. Corner sorter temporarily uses C++ STL's quick sort. A parallel selection sort in OpneCL is contained in the implementation but disabled due to poor performance at the moment. 5. Accuracy test for ocl gfft.
This commit is contained in:
+25
-15
@@ -782,45 +782,55 @@ static void arithmetic_minMax_mask_run(const oclMat &src, const oclMat &mask, cl
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> void arithmetic_minMax(const oclMat &src, double *minVal, double *maxVal, const oclMat &mask)
|
||||
template <typename T> void arithmetic_minMax(const oclMat &src, double *minVal, double *maxVal,
|
||||
const oclMat &mask, oclMat &buf)
|
||||
{
|
||||
size_t groupnum = src.clCxt->computeUnits();
|
||||
CV_Assert(groupnum != 0);
|
||||
groupnum = groupnum * 2;
|
||||
int vlen = 8;
|
||||
int dbsize = groupnum * 2 * vlen * sizeof(T) ;
|
||||
Context *clCxt = src.clCxt;
|
||||
cl_mem dstBuffer = openCLCreateBuffer(clCxt, CL_MEM_WRITE_ONLY, dbsize);
|
||||
*minVal = std::numeric_limits<double>::max() , *maxVal = -std::numeric_limits<double>::max();
|
||||
|
||||
ensureSizeIsEnough(1, dbsize, CV_8UC1, buf);
|
||||
|
||||
cl_mem buf_data = reinterpret_cast<cl_mem>(buf.data);
|
||||
|
||||
if (mask.empty())
|
||||
{
|
||||
arithmetic_minMax_run(src, mask, dstBuffer, vlen, groupnum, "arithm_op_minMax");
|
||||
arithmetic_minMax_run(src, mask, buf_data, vlen, groupnum, "arithm_op_minMax");
|
||||
}
|
||||
else
|
||||
{
|
||||
arithmetic_minMax_mask_run(src, mask, dstBuffer, vlen, groupnum, "arithm_op_minMax_mask");
|
||||
arithmetic_minMax_mask_run(src, mask, buf_data, vlen, groupnum, "arithm_op_minMax_mask");
|
||||
}
|
||||
T *p = new T[groupnum * vlen * 2];
|
||||
memset(p, 0, dbsize);
|
||||
openCLReadBuffer(clCxt, dstBuffer, (void *)p, dbsize);
|
||||
if(minVal != NULL){
|
||||
|
||||
Mat matbuf = Mat(buf);
|
||||
T *p = matbuf.ptr<T>();
|
||||
if(minVal != NULL)
|
||||
{
|
||||
*minVal = std::numeric_limits<double>::max();
|
||||
for(int i = 0; i < vlen * (int)groupnum; i++)
|
||||
{
|
||||
*minVal = *minVal < p[i] ? *minVal : p[i];
|
||||
}
|
||||
}
|
||||
if(maxVal != NULL){
|
||||
if(maxVal != NULL)
|
||||
{
|
||||
*maxVal = -std::numeric_limits<double>::max();
|
||||
for(int i = vlen * (int)groupnum; i < 2 * vlen * (int)groupnum; i++)
|
||||
{
|
||||
*maxVal = *maxVal > p[i] ? *maxVal : p[i];
|
||||
}
|
||||
}
|
||||
delete[] p;
|
||||
openCLFree(dstBuffer);
|
||||
}
|
||||
|
||||
typedef void (*minMaxFunc)(const oclMat &src, double *minVal, double *maxVal, const oclMat &mask);
|
||||
typedef void (*minMaxFunc)(const oclMat &src, double *minVal, double *maxVal, const oclMat &mask, oclMat &buf);
|
||||
void cv::ocl::minMax(const oclMat &src, double *minVal, double *maxVal, const oclMat &mask)
|
||||
{
|
||||
oclMat buf;
|
||||
minMax_buf(src, minVal, maxVal, mask, buf);
|
||||
}
|
||||
void cv::ocl::minMax_buf(const oclMat &src, double *minVal, double *maxVal, const oclMat &mask, oclMat &buf)
|
||||
{
|
||||
CV_Assert(src.oclchannels() == 1);
|
||||
if(!src.clCxt->supportsFeature(Context::CL_DOUBLE) && src.depth() == CV_64F)
|
||||
@@ -840,7 +850,7 @@ void cv::ocl::minMax(const oclMat &src, double *minVal, double *maxVal, const oc
|
||||
};
|
||||
minMaxFunc func;
|
||||
func = functab[src.depth()];
|
||||
func(src, minVal, maxVal, mask);
|
||||
func(src, minVal, maxVal, mask, buf);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Reference in New Issue
Block a user