36 #include <visp3/core/vpCannyEdgeDetection.h>
37 #include <visp3/core/vpException.h>
38 #include <visp3/core/vpImageConvert.h>
39 #include <visp3/core/vpImageFilter.h>
40 #include <visp3/core/vpRGBa.h>
116 unsigned int size = kernelH.
size();
117 unsigned int half_size = size / 2;
122 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
123 for (
unsigned int j = half_size; j < I.
getWidth() - half_size; j++) {
125 for (
unsigned int a = 0; a < kernelH.
size(); a++) {
126 conv += kernelH[a] * I[i][j + half_size - a];
129 I_filter[i][j] = conv;
133 for (
unsigned int i = half_size; i < I.
getHeight() - half_size; i++) {
134 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
136 for (
unsigned int a = 0; a < kernelV.
size(); a++) {
137 conv += kernelV[a] * I_filter[i + half_size - a][j];
145 #if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
153 float m = (channel.rows * channel.cols) / 2.f;
158 float range[] = { 0, 256 };
159 const float *histRange = { range };
161 bool accumulate =
false;
163 cv::calcHist(&channel, 1, 0, cv::Mat(), hist, 1, &histSize, &histRange, uniform, accumulate);
165 for (
int i = 0; i < histSize && med < 0.0; ++i) {
166 bin += cvRound(hist.at<
float>(i));
167 if (bin > m && med < 0.0)
168 med =
static_cast<float>(i);
200 std::vector<cv::Mat> channels;
201 cv::split(cv_I_bgr, channels);
202 std::vector<float> meds(3);
203 const int orderMeds[] = { 2, 1, 0 };
204 const int orderCvChannels[] = { 0, 1, 2 };
205 for (
unsigned int i = 0; i < 3; i++) {
206 meds[orderMeds[i]] =
median(channels[orderCvChannels[i]]);
222 if (p_cv_blur !=
nullptr) {
223 cv_I_blur = *p_cv_blur;
226 cv::GaussianBlur(cv_I, cv_I_blur, cv::Size(9, 9), 2, 2);
231 int orig_size = std::min(
static_cast<int>(cv_I.rows),
static_cast<int>(cv_I.cols));
232 int scale_down = std::max(1,
static_cast<int>(orig_size / req_size));
233 cv::Mat cv_I_scaled_down;
234 resize(cv_I_blur, cv_I_scaled_down, cv::Size(), scale_down, scale_down, cv::INTER_NEAREST);
237 float lower = std::max(0.f, 0.7f * median_pix);
238 float upper = std::min(255.f, 1.3f * median_pix);
239 upper = std::max(1.f, upper);
299 unsigned int gaussianFilterSize,
float thresholdCanny,
unsigned int apertureSobel)
301 vpImageFilter::canny(Isrc, Ires, gaussianFilterSize, thresholdCanny / 3.f, thresholdCanny, apertureSobel);
348 unsigned int gaussianFilterSize,
float lowerThreshold,
float upperThreshold,
unsigned int apertureSobel)
350 #if defined(HAVE_OPENCV_IMGPROC)
351 cv::Mat img_cvmat, cv_I_blur, cv_dx, cv_dy, edges_cvmat;
353 cv::GaussianBlur(img_cvmat, cv_I_blur, cv::Size((
int)gaussianFilterSize, (
int)gaussianFilterSize), 0, 0);
354 cv::Sobel(cv_I_blur, cv_dx, CV_16S, 1, 0, apertureSobel);
355 cv::Sobel(cv_I_blur, cv_dy, CV_16S, 0, 1, apertureSobel);
356 float upperCannyThresh = upperThreshold;
357 float lowerCannyThresh = lowerThreshold;
358 if (upperCannyThresh < 0) {
361 else if (lowerCannyThresh < 0) {
362 lowerCannyThresh = upperCannyThresh / 3.f;
364 cv::Canny(cv_dx, cv_dy, edges_cvmat, lowerCannyThresh, upperCannyThresh,
false);
368 float upperCannyThresh = upperThreshold;
369 float lowerCannyThresh = lowerThreshold;
370 if (upperCannyThresh < 0) {
373 else if (lowerCannyThresh < 0) {
374 lowerCannyThresh = upperCannyThresh / 3.;
377 Ires = edgeDetector.
detect(Isrc);
412 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
413 for (
unsigned int j = 0; j < (size - 1) / 2; j++) {
418 for (
unsigned int j = (size - 1) / 2; j < I.
getWidth() - (size - 1) / 2; j++) {
423 for (
unsigned int j = I.
getWidth() - (size - 1) / 2; j < I.
getWidth(); j++) {
454 for (
unsigned int i = 0; i < (size - 1) / 2; i++) {
455 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
461 for (
unsigned int i = (size - 1) / 2; i < I.
getHeight() - (size - 1) / 2; i++) {
462 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
469 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
487 for (
unsigned int i = 0; i < (size - 1) / 2; i++) {
488 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
492 for (
unsigned int i = (size - 1) / 2; i < I.
getHeight() - (size - 1) / 2; i++) {
493 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
498 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
526 double *fg =
new double[(size + 1) / 2];
545 void vpImageFilter::getGaussianKernel<float>(
float *filter,
unsigned int size,
float sigma,
bool normalize);
548 void vpImageFilter::getGaussianDerivativeKernel<float>(
float *filter,
unsigned int size,
float sigma,
bool normalize);
551 void vpImageFilter::getGaussianDerivativeKernel<double>(
double *filter,
unsigned int size,
double sigma,
bool normalize);
591 const float *gaussianDerivativeKernel,
unsigned int size);
595 const double *gaussianDerivativeKernel,
unsigned int size);
599 const float *gaussianDerivativeKernel,
unsigned int size);
603 const double *gaussianDerivativeKernel,
unsigned int size);
607 const float *gaussianDerivativeKernel,
unsigned int size);
611 const double *gaussianDerivativeKernel,
unsigned int size);
615 const float *gaussianDerivativeKernel,
unsigned int size);
619 const double *gaussianDerivativeKernel,
unsigned int size);
628 #if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
629 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
630 cv::Mat imgsrc, imgdest;
632 cv::pyrDown(imgsrc, imgdest, cv::Size((
int)I.
getWidth() / 2, (
int)I.
getHeight() / 2));
635 cv::Mat imgsrc, imgdest;
637 cv::pyrDown(imgsrc, imgdest, cvSize((
int)I.
getWidth() / 2, (
int)I.
getHeight() / 2));
651 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
653 for (
unsigned int j = 1; j < w - 1; j++) {
656 GI[i][w - 1] = I[i][2 * w - 1];
665 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
667 for (
unsigned int i = 1; i < h - 1; i++) {
670 GI[h - 1][j] = I[2 * h - 1][j];
678 double vpImageFilter::getSobelKernelX<double>(
double *filter,
unsigned int size);
681 float vpImageFilter::getSobelKernelX<float>(
float *filter,
unsigned int size);
684 double vpImageFilter::getSobelKernelY<double>(
double *filter,
unsigned int size);
687 float vpImageFilter::getSobelKernelY<float>(
float *filter,
unsigned int size);
unsigned int size() const
Return the number of elements of the 2D array.
vpImage< unsigned char > detect(const vpImage< vpRGBa > &I_color)
Detect the edges in an image. Convert the color image into a gray-scale image.
Implementation of column vector and the associated operations.
error that can be emitted by ViSP classes.
@ badValue
Used to indicate that a value is not in the allowed range.
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
static unsigned char filterGaussXPyramidal(const vpImage< unsigned char > &I, unsigned int i, unsigned int j)
static double filterYTopBorderG(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static void filterYB(const vpImage< vpRGBa > &I, vpImage< vpRGBa > &dIx, const double *filter, unsigned int size)
static double filterYBottomBorderB(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static float computeCannyThreshold(const cv::Mat &cv_I, const cv::Mat *p_cv_blur, float &lowerThresh)
Compute the upper Canny edge filter threshold.
static void filterX(const vpImage< unsigned char > &I, vpImage< FilterType > &dIx, const FilterType *filter, unsigned int size)
static double filterXRightBorderB(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static double filterYBottomBorderR(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static double filterYTopBorderB(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static void filterXB(const vpImage< vpRGBa > &I, vpImage< vpRGBa > &dIx, const double *filter, unsigned int size)
static double filterXLeftBorderB(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static void filterYR(const vpImage< vpRGBa > &I, vpImage< vpRGBa > &dIx, const double *filter, unsigned int size)
static void sepFilter(const vpImage< unsigned char > &I, vpImage< double > &If, const vpColVector &kernelH, const vpColVector &kernelV)
static void gaussianBlur(const vpImage< unsigned char > &I, vpImage< FilterType > &GI, unsigned int size=7, FilterType sigma=0., bool normalize=true)
static double filterXLeftBorderR(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static FilterType filterYBottomBorder(const vpImage< unsigned char > &I, unsigned int r, unsigned int c, const FilterType *filter, unsigned int size)
static double filterXLeftBorderG(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static double filterXRightBorderR(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static void filterXR(const vpImage< vpRGBa > &I, vpImage< vpRGBa > &dIx, const double *filter, unsigned int size)
static void getGaussXPyramidal(const vpImage< unsigned char > &I, vpImage< unsigned char > &GI)
static void getGaussianKernel(FilterType *filter, unsigned int size, FilterType sigma=0., bool normalize=true)
static double filterYTopBorderR(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static void filterYG(const vpImage< vpRGBa > &I, vpImage< vpRGBa > &dIx, const double *filter, unsigned int size)
static void getGaussYPyramidal(const vpImage< unsigned char > &I, vpImage< unsigned char > &GI)
static float median(const cv::Mat &cv_I)
Calculates the median value of a single channel. The algorithm is based on based on https://github....
static double filterXRightBorderG(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static void filterY(const vpImage< unsigned char > &I, vpImage< FilterType > &dIy, const FilterType *filter, unsigned int size)
static void filter(const vpImage< unsigned char > &I, vpImage< FilterType > &If, const vpArray2D< FilterType > &M, bool convolve=false)
static void filterXG(const vpImage< vpRGBa > &I, vpImage< vpRGBa > &dIx, const double *filter, unsigned int size)
static void canny(const vpImage< unsigned char > &I, vpImage< unsigned char > &Ic, unsigned int gaussianFilterSize, float thresholdCanny, unsigned int apertureSobel)
static FilterType filterYTopBorder(const vpImage< unsigned char > &I, unsigned int r, unsigned int c, const FilterType *filter, unsigned int size)
static double filterYBottomBorderG(const vpImage< vpRGBa > &I, unsigned int r, unsigned int c, const double *filter, unsigned int size)
static unsigned char filterGaussYPyramidal(const vpImage< unsigned char > &I, unsigned int i, unsigned int j)
static void getGaussPyramidal(const vpImage< unsigned char > &I, vpImage< unsigned char > &GI)
void destroy()
Destructor : Memory de-allocation.
unsigned int getWidth() const
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
unsigned int getHeight() const