Commit c2903700 authored by Alexander Alekhin's avatar Alexander Alekhin

Merge pull request #918 from LaurentBerger:ImprovePaillou

parents 1050104e 7360642d
...@@ -51,8 +51,8 @@ namespace ximgproc { ...@@ -51,8 +51,8 @@ namespace ximgproc {
* *
* For more details about this implementation, please see @cite paillou1997detecting * For more details about this implementation, please see @cite paillou1997detecting
* *
* @param op Source 8-bit or 16bit image, 1-channel or 3-channel image. * @param op Source CV_8U(S) or CV_16U(S), 1-channel or 3-channels image.
* @param _dst result CV_32F image with same numeber of channel than op. * @param _dst result CV_32F image with same number of channel than op.
* @param omega double see paper * @param omega double see paper
* @param alpha double see paper * @param alpha double see paper
* *
......
...@@ -47,8 +47,8 @@ using namespace cv::ximgproc; ...@@ -47,8 +47,8 @@ using namespace cv::ximgproc;
using namespace std; using namespace std;
int aa = 100, ww = 10; int aa = 100, ww = 10;
Mat dx, dy;
UMat img; Ptr<Mat> img;
const char* window_name = "Gradient Modulus"; const char* window_name = "Gradient Modulus";
static void DisplayImage(Mat x,string s) static void DisplayImage(Mat x,string s)
...@@ -77,8 +77,8 @@ static void PaillouFilter(int, void*) ...@@ -77,8 +77,8 @@ static void PaillouFilter(int, void*)
Mat dst; Mat dst;
double a=aa/100.0,w=ww/100.0; double a=aa/100.0,w=ww/100.0;
Mat rx,ry; Mat rx,ry;
GradientPaillouX(img,rx,a,w); GradientPaillouX(*img.get(),rx,a,w);
GradientPaillouY(img,ry,a,w); GradientPaillouY(*img.get(),ry,a,w);
DisplayImage(rx, "Gx"); DisplayImage(rx, "Gx");
DisplayImage(ry, "Gy"); DisplayImage(ry, "Gy");
add(rx.mul(rx),ry.mul(ry),dst); add(rx.mul(rx),ry.mul(ry),dst);
...@@ -89,13 +89,15 @@ static void PaillouFilter(int, void*) ...@@ -89,13 +89,15 @@ static void PaillouFilter(int, void*)
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
if (argc==2) Mat *m=new Mat;
imread(argv[1]).copyTo(img); if (argc == 2)
if (img.empty()) *m = imread(argv[1]);
if (m->empty())
{ {
cout << "File not found or empty image\n"; cout << "File not found or empty image\n";
} }
imshow("Original",img); img = Ptr<Mat>(m);
imshow("Original",*img.get());
namedWindow( window_name, WINDOW_AUTOSIZE ); namedWindow( window_name, WINDOW_AUTOSIZE );
/// Create a Trackbar for user to enter threshold /// Create a Trackbar for user to enter threshold
......
/*
* By downloading, copying, installing or using the software you agree to this license.
* If you do not agree to this license, do not download, install,
* copy or use the software.
*
*
* License Agreement
* For Open Source Computer Vision Library
* (3 - clause BSD License)
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met :
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and / or other materials provided with the distribution.
*
* * Neither the names of the copyright holders nor the names of the contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* This software is provided by the copyright holders and contributors "as is" and
* any express or implied warranties, including, but not limited to, the implied
* warranties of merchantability and fitness for a particular purpose are disclaimed.
* In no event shall copyright holders or contributors be liable for any direct,
* indirect, incidental, special, exemplary, or consequential damages
* (including, but not limited to, procurement of substitute goods or services;
* loss of use, data, or profits; or business interruption) however caused
* and on any theory of liability, whether in contract, strict liability,
* or tort(including negligence or otherwise) arising in any way out of
* the use of this software, even if advised of the possibility of such damage.
*/
#include "precomp.hpp" #include "precomp.hpp"
#include "opencv2/highgui.hpp" #include "opencv2/highgui.hpp"
#include <math.h> #include <math.h>
#include <vector> #include <vector>
#include <iostream> #include <iostream>
namespace cv {
namespace ximgproc {
/* /*
If you use this code please cite this @cite paillou1997detecting If you use this code please cite this @cite paillou1997detecting
Detecting step edges in noisy SAR images: a new linear operator IEEE Transactions on Geoscience and Remote Sensing (Volume:35 , Issue: 1 ) 1997 Detecting step edges in noisy SAR images: a new linear operator IEEE Transactions on Geoscience and Remote Sensing (Volume:35 , Issue: 1 ) 1997
Equation xx pyyy mean equation xx at page yyy in previous paper
*/ */
namespace cv {
namespace ximgproc {
template<typename T> static void
VerticalIIRFilter(Mat &img, Mat &dst, const Range &range, double a,double w)
{
float *f2;
int tailleSequence = (img.rows>img.cols) ? img.rows : img.cols;
Mat matYp(1, tailleSequence, CV_64FC1), matYm(1, tailleSequence, CV_64FC1);
double *yp = matYp.ptr<double>(0), *ym = matYm.ptr<double>(0);
int rows = img.rows, cols = img.cols;
// Equation 12 p193
double b1 = -2 * exp(-a)*cosh(w);
double a1 = 2 * exp(-a)*cosh(w) - exp(-2 * a) - 1;
double b2 = exp(-2 * a);
for (int j = range.start; j < range.end; j++)
{
// Equation 26 p194
T *c1 = (T *)img.ptr(0) + j;
f2 = dst.ptr<float>(0) + j;
double border = *c1;
yp[0] = *c1;
c1 += cols;
yp[1] = *c1 - b1*yp[0] - b2*border;
c1 += cols;
for (int i = 2; i < rows; i++, c1 += cols)
yp[i] = *c1 - b1*yp[i - 1] - b2*yp[i - 2];
// Equation 27 p194
c1 = (T *)img.ptr(rows - 1) + j;
border = *c1;
ym[rows - 1] = *c1;
c1 -= cols;
ym[rows - 2] = *c1 - b1*ym[rows - 1];
c1 -= cols;
for (int i = rows - 3; i >= 0; i--, c1 -= cols)
ym[i] = *c1 - b1*ym[i + 1] - b2*ym[i + 2];
// Equation 25 p193
for (int i = 0; i < rows; i++, f2 += cols)
*f2 = (float)(a1*(ym[i] - yp[i]));
}
}
template<typename T> static void
HorizontalIIRFilter(Mat &img, Mat &dst, const Range &range, double a, double w)
{
int tailleSequence = (img.rows>img.cols) ? img.rows : img.cols;
Mat matYp(1, tailleSequence, CV_64FC1), matYm(1, tailleSequence, CV_64FC1);
double *yp = matYp.ptr<double>(0), *ym = matYm.ptr<double>(0);
int cols = img.cols;
float *f2;
// Equation 12 p193
double b1 = -2 * exp(-a)*cosh(w);
double a1 = 2 * exp(-a)*cosh(w) - exp(-2 * a) - 1;
double b2 = exp(-2 * a);
for (int i = range.start; i<range.end; i++)
{
// Equation 26 p194
T *c1 = img.ptr<T>(i);
double border = *c1;
yp[0] = *c1;
c1++;
yp[1] = *c1 - b1*yp[0] - b2*border;
c1++;
for (int j = 2; j<cols; j++, c1++)
yp[j] = *c1 - b1*yp[j - 1] - b2*yp[j - 2];
// Equation 27 p194
c1 = img.ptr<T>(i) + cols - 1;
border = *c1;
ym[cols - 1] = *c1;
c1--;
ym[cols - 2] = *c1 - b1*ym[cols - 1];
c1--;
for (int j = cols - 3; j >= 0; j--, c1--)
ym[j] = *c1 - b1*ym[j + 1] - b2*ym[j + 2];
// Equation 25 p193
f2 = dst.ptr<float>(i);
for (int j = 0; j<cols; j++, f2++)
*f2 = (float)(a1*(ym[j] - yp[j]));
}
}
class ParallelGradientPaillouYCols: public ParallelLoopBody class ParallelGradientPaillouYCols: public ParallelLoopBody
{ {
...@@ -36,98 +152,19 @@ public: ...@@ -36,98 +152,19 @@ public:
CV_Assert(dst.depth()==CV_32FC1); CV_Assert(dst.depth()==CV_32FC1);
if (verbose) if (verbose)
std::cout << getThreadNum()<<"# :Start from row " << range.start << " to " << range.end-1<<" ("<<range.end-range.start<<" loops)" << std::endl; std::cout << getThreadNum()<<"# :Start from row " << range.start << " to " << range.end-1<<" ("<<range.end-range.start<<" loops)" << std::endl;
float *f2;
int tailleSequence=(img.rows>img.cols)?img.rows:img.cols;
Mat matYp(1,tailleSequence,CV_64FC1), matYm(1,tailleSequence,CV_64FC1);
double *yp=matYp.ptr<double>(0), *ym=matYm.ptr<double>(0);
int rows=img.rows,cols=img.cols;
// Equation 12 p193
double b1=-2*exp(-a)*cosh(w);
double a1=2*exp(-a)*cosh(w)-exp(-2*a)-1;
double b2=exp(-2*a);
switch(img.depth()){ switch(img.depth()){
case CV_8U : case CV_8U:
for (int j=range.start;j<range.end;j++) VerticalIIRFilter<uchar>(img, dst, range, a, w);
{ break;
// Equation 26 p194 case CV_8S:
uchar *c1 = img.ptr(0)+j; VerticalIIRFilter<char>(img, dst, range, a, w);
f2 = dst.ptr<float>(0)+j;
double border=*c1;
yp[0] = *c1 ;
c1+=cols;
yp[1] = *c1 - b1*yp[0]-b2*border;
c1+=cols;
for (int i=2;i<rows;i++,c1+=cols)
yp[i] = *c1-b1*yp[i-1]-b2*yp[i-2];
// Equation 27 p194
c1 = img.ptr(rows-1)+j;
border=*c1;
ym[rows - 1] = *c1;
c1 -= cols;
ym[rows-2] =*c1 - b1*ym[rows-1];
c1 -= cols;
for (int i=rows-3;i>=0;i--,c1-=cols)
ym[i]=*c1-b1*ym[i+1]-b2*ym[i+2];
// Equation 25 p193
for (int i=0;i<rows;i++,f2+=cols)
*f2 = (float)(a1*(ym[i]-yp[i]));
}
break; break;
case CV_16S : case CV_16S :
for (int j = range.start; j<range.end; j++) VerticalIIRFilter<short>(img, dst, range, a, w);
{ break;
// Equation 26 p194
short *c1 = img.ptr<short>(0) + j;
f2 = dst.ptr<float>(0) + j;
double border = *c1;
yp[0] = *c1;
c1 += cols;
yp[1] = *c1 - b1*yp[0] - b2*border;
c1 += cols;
for (int i = 2; i<rows; i++, c1 += cols)
yp[i] = *c1 - b1*yp[i - 1] - b2*yp[i - 2];
// Equation 27 p194
c1 = img.ptr<short>(rows - 1) + j;
border = *c1;
ym[rows - 1] = *c1;
c1 -= cols;
ym[rows - 2] = *c1 - b1*ym[rows - 1];
c1 -= cols;
for (int i = rows - 3; i >= 0; i--, c1 -= cols)
ym[i] = *c1 - b1*ym[i + 1] - b2*ym[i + 2];
// Equation 25 p193
for (int i = 0; i<rows; i++, f2 += cols)
*f2 = (float)(a1*(ym[i] - yp[i]));
}
break;
case CV_16U : case CV_16U :
for (int j = range.start; j<range.end; j++) VerticalIIRFilter<short>(img, dst, range, a, w);
{
// Equation 26 p194
ushort *c1 = img.ptr<ushort>(0) + j;
f2 = dst.ptr<float>(0) + j;
double border = *c1;
yp[0] = *c1;
c1 += cols;
yp[1] = *c1 - b1*yp[0] - b2*border;
c1 += cols;
for (int i = 2; i<rows; i++, c1 += cols)
yp[i] = *c1 - b1*yp[i - 1] - b2*yp[i - 2];
// Equation 27 p194
c1 = img.ptr<ushort>(rows - 1) + j;
border = *c1;
ym[rows - 1] = *c1;
c1 -= cols;
ym[rows - 2] = *c1 - b1*ym[rows - 1];
c1 -= cols;
for (int i = rows - 3; i >= 0; i--, c1 -= cols)
ym[i] = *c1 - b1*ym[i + 1] - b2*ym[i + 2];
// Equation 25 p193
for (int i = 0; i<rows; i++, f2 += cols)
*f2 = (float)(a1*(ym[i] - yp[i]));
}
break; break;
default : default :
return ; return ;
...@@ -301,125 +338,20 @@ public: ...@@ -301,125 +338,20 @@ public:
{ {
if (verbose) if (verbose)
std::cout << getThreadNum()<<"# :Start from row " << range.start << " to " << range.end-1<<" ("<<range.end-range.start<<" loops)" << std::endl; std::cout << getThreadNum()<<"# :Start from row " << range.start << " to " << range.end-1<<" ("<<range.end-range.start<<" loops)" << std::endl;
float *f2;
int tailleSequence = (img.rows>img.cols) ? img.rows : img.cols;
Mat matYp(1,tailleSequence,CV_64FC1), matYm(1,tailleSequence,CV_64FC1);
double *yp=matYp.ptr<double>(0), *ym=matYm.ptr<double>(0);
int cols = img.cols;
// Equation 12 p193 // Equation 12 p193
double b1 = -2 * exp(-a)*cosh(w);
double a1 = 2 * exp(-a)*cosh(w) - exp(-2 * a) - 1;
double b2 = exp(-2 * a);
switch(img.depth()){ switch(img.depth()){
case CV_8U : case CV_8U :
for (int i = range.start; i<range.end; i++) HorizontalIIRFilter<uchar>(img,im1,range,a,w);
{
// Equation 26 p194
uchar *c1 = img.ptr(i);
double border = *c1;
yp[0] = *c1;
c1++;
yp[1] = *c1 - b1*yp[0] - b2*border;
c1++;
for (int j = 2; j<cols; j++, c1++)
yp[j] = *c1 - b1*yp[j - 1] - b2*yp[j - 2];
// Equation 27 p194
c1 = img.ptr(i)+cols-1;
border = *c1;
ym[cols - 1] = *c1;
c1--;
ym[cols - 2] = *c1 - b1*ym[cols - 1];
c1--;
for (int j = cols - 3; j >= 0; j--, c1--)
ym[j] = *c1 - b1*ym[j + 1] - b2*ym[j + 2];
// Equation 25 p193
f2 = im1.ptr<float>(i);
for (int j = 0; j<cols; j++, f2 ++)
*f2 = (float)(a1*(ym[j] - yp[j]));
}
break; break;
case CV_8S : case CV_8S :
for (int i = range.start; i<range.end; i++) HorizontalIIRFilter<char>(img, im1, range, a, w);
{
// Equation 26 p194
char *c1 = img.ptr<char>(i);
double border = *c1;
yp[0] = *c1;
c1++;
yp[1] = *c1 - b1*yp[0] - b2*border;
c1++;
for (int j = 2; j<cols; j++, c1++)
yp[j] = *c1 - b1*yp[j - 1] - b2*yp[j - 2];
// Equation 27 p194
c1 = img.ptr<char>(i)+cols-1;
border = *c1;
ym[cols - 1] = *c1;
c1--;
ym[cols - 2] = *c1 - b1*ym[cols - 1];
c1--;
for (int j = cols - 3; j >= 0; j--, c1--)
ym[j] = *c1 - b1*ym[j + 1] - b2*ym[j + 2];
// Equation 25 p193
f2 = im1.ptr<float>(i);
for (int j = 0; j<cols; j++, f2 ++)
*f2 = (float)(a1*(ym[j] - yp[j]));
}
break; break;
case CV_16S : case CV_16S :
for (int i = range.start; i<range.end; i++) HorizontalIIRFilter<short>(img, im1, range, a, w);
{
// Equation 26 p194
short *c1 = img.ptr<short>(i);
f2 = im1.ptr<float>(i);
double border = *c1;
yp[0] = *c1;
c1++;
yp[1] = *c1 - b1*yp[0] - b2*border;
c1++;
for (int j = 2; j<cols; j++, c1++)
yp[j] = *c1 - b1*yp[j - 1] - b2*yp[j - 2];
// Equation 27 p194
c1 = img.ptr<short>(i) + cols - 1;
border = *c1;
ym[cols - 1] = *c1;
c1--;
ym[cols - 2] = *c1 - b1*ym[cols - 1];
c1--;
for (int j = cols - 3; j >= 0; j--, c1--)
ym[j] = *c1 - b1*ym[j + 1] - b2*ym[j + 2];
// Equation 25 p193
for (int j = 0; j<cols; j++, f2++)
*f2 = (float)(a1*(ym[i] - yp[i]));
}
break; break;
case CV_16U : case CV_16U :
for (int i = range.start; i<range.end; i++) HorizontalIIRFilter<ushort>(img, im1, range, a, w);
{
// Equation 26 p194
ushort *c1 = img.ptr<ushort>(i);
f2 = im1.ptr<float>(i);
double border = *c1;
yp[0] = *c1;
c1++;
yp[1] = *c1 - b1*yp[0] - b2*border;
c1++;
for (int j = 2; j<cols; j++, c1++)
yp[j] = *c1 - b1*yp[j - 1] - b2*yp[j - 2];
// Equation 27 p194
c1 = img.ptr<ushort>(i) + cols - 1;
border = *c1;
ym[cols - 1] = *c1;
c1--;
ym[cols - 2] = *c1 - b1*ym[cols - 1];
c1--;
for (int j = cols - 3; j >= 0; j--, c1--)
ym[j] = *c1 - b1*ym[j + 1] - b2*ym[j + 2];
// Equation 25 p193
for (int j = 0; j<cols; j++, f2++)
*f2 = (float)(a1*(ym[i] - yp[i]));
}
break; break;
default : default :
return ; return ;
...@@ -432,53 +364,38 @@ public: ...@@ -432,53 +364,38 @@ public:
void GradientPaillouY(InputArray _op, OutputArray _dst, double alpha, double omega) void GradientPaillouY(InputArray _op, OutputArray _dst, double alpha, double omega)
{ {
Mat tmp(_op.size(),CV_32FC(_op.channels()));
_dst.create( _op.size(),CV_32FC(tmp.channels()) );
cv::Mat opSrc = _op.getMat();
std::vector<Mat> planSrc; std::vector<Mat> planSrc;
split(opSrc,planSrc); split(_op,planSrc);
std::vector<Mat> planTmp; std::vector<Mat> planTmp;
split(tmp,planTmp);
std::vector<Mat> planDst; std::vector<Mat> planDst;
split(_dst,planDst); for (int i = 0; i <static_cast<int>(planSrc.size()); i++)
for (int i = 0; i < static_cast<int>(planSrc.size()); i++)
{ {
if (planSrc[i].isContinuous() && planTmp[i].isContinuous() && planDst[i].isContinuous()) planTmp.push_back(Mat(_op.size(), CV_32FC1));
{ planDst.push_back(Mat(_op.size(), CV_32FC1));
ParallelGradientPaillouYCols x(planSrc[i],planTmp[i],alpha,omega); CV_Assert(planSrc[i].isContinuous() && planTmp[i].isContinuous() && planDst[i].isContinuous());
parallel_for_(Range(0,opSrc.cols), x,getNumThreads()); ParallelGradientPaillouYCols x(planSrc[i],planTmp[i],alpha,omega);
ParallelGradientPaillouYRows xr(planTmp[i],planDst[i],alpha,omega); parallel_for_(Range(0, planSrc[i].cols), x,getNumThreads());
parallel_for_(Range(0,opSrc.rows), xr,getNumThreads()); ParallelGradientPaillouYRows xr(planTmp[i],planDst[i],alpha,omega);
parallel_for_(Range(0, planTmp[i].rows), xr,getNumThreads());
}
else
std::cout << "PB";
} }
merge(planDst,_dst); merge(planDst,_dst);
} }
void GradientPaillouX(InputArray _op, OutputArray _dst, double alpha, double omega) void GradientPaillouX(InputArray _op, OutputArray _dst, double alpha, double omega)
{ {
Mat tmp(_op.size(),CV_32FC(_op.channels()));
_dst.create( _op.size(),CV_32FC(tmp.channels()) );
Mat opSrc = _op.getMat();
std::vector<Mat> planSrc; std::vector<Mat> planSrc;
split(opSrc,planSrc); split(_op,planSrc);
std::vector<Mat> planTmp; std::vector<Mat> planTmp;
split(tmp,planTmp);
std::vector<Mat> planDst; std::vector<Mat> planDst;
split(_dst,planDst); for (int i = 0; i <static_cast<int>(planSrc.size()); i++)
for (int i = 0; i < static_cast<int>(planSrc.size()); i++)
{ {
if (planSrc[i].isContinuous() && planTmp[i].isContinuous() && planDst[i].isContinuous()) planTmp.push_back(Mat(_op.size(), CV_32FC1));
{ planDst.push_back(Mat(_op.size(), CV_32FC1));
ParallelGradientPaillouXRows x(planSrc[i],planTmp[i],alpha,omega); CV_Assert(planSrc[i].isContinuous() && planTmp[i].isContinuous() && planDst[i].isContinuous());
parallel_for_(Range(0,opSrc.rows), x,getNumThreads()); ParallelGradientPaillouXRows x(planSrc[i],planTmp[i],alpha,omega);
ParallelGradientPaillouXCols xr(planTmp[i],planDst[i],alpha,omega); parallel_for_(Range(0, planSrc[i].rows), x,getNumThreads());
parallel_for_(Range(0,opSrc.cols), xr,getNumThreads()); ParallelGradientPaillouXCols xr(planTmp[i],planDst[i],alpha,omega);
} parallel_for_(Range(0, planTmp[i].cols), xr,getNumThreads());
else
std::cout << "PB";
} }
merge(planDst,_dst); merge(planDst,_dst);
} }
......
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