39 #include <visp3/core/vpCPUFeatures.h> 40 #include <visp3/core/vpImageConvert.h> 41 #include <visp3/core/vpImageTools.h> 43 #include <Simd/SimdLib.hpp> 102 unsigned char B_star)
111 double factor = (double)(B_star - A_star) / (double)(B - A);
113 for (
unsigned int i = 0; i < I.
getHeight(); i++)
114 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
122 I[i][j] = (
unsigned char)(A_star + factor * (v - A));
169 "(%ux%u) and (%ux%u) have not the same size",
177 SimdImageDifference(reinterpret_cast<unsigned char *>(I1.
bitmap), reinterpret_cast<unsigned char *>(I2.
bitmap),
178 I1.
getSize()*4,
reinterpret_cast<unsigned char *
>(Idiff.
bitmap));
203 for (
unsigned int b = 0; b < n; b++) {
227 for (
unsigned int b = 0; b < n; b++) {
256 for (
unsigned int b = 0; b < n; b++) {
293 typedef Simd::View<Simd::Allocator> View;
298 Simd::OperationBinary8u(img1, img2, imgAdd, saturate ? SimdOperationBinary8uSaturatedAddition : SimdOperationBinary8uAddition);
325 typedef Simd::View<Simd::Allocator> View;
330 Simd::OperationBinary8u(img1, img2, imgAdd, saturate ? SimdOperationBinary8uSaturatedSubtraction : SimdOperationBinary8uSubtraction);
348 mapU.
resize(height, width,
false,
false);
349 mapV.
resize(height, width,
false,
false);
350 mapDu.
resize(height, width,
false,
false);
351 mapDv.
resize(height, width,
false,
false);
356 float u0 =
static_cast<float>(cam.
get_u0());
357 float v0 =
static_cast<float>(cam.
get_v0());
358 float px =
static_cast<float>(cam.
get_px());
359 float py =
static_cast<float>(cam.
get_py());
361 std::vector<double> dist_coefs;
363 if(!is_KannalaBrandt)
364 kud =
static_cast<float>(cam.
get_kud());
369 if (!is_KannalaBrandt && std::fabs(static_cast<double>(kud)) <= std::numeric_limits<double>::epsilon()) {
371 for (
unsigned int i = 0; i < height; i++) {
372 for (
unsigned int j = 0; j < width; j++) {
373 mapU[i][j] =
static_cast<int>(j);
374 mapV[i][j] =
static_cast<int>(i);
384 float kud_px2 = 0., kud_py2 = 0., deltau_px, deltav_py;
386 float deltav, deltau;
387 float u_float, v_float;
388 int u_round, v_round;
390 double theta, theta_d;
391 double theta2, theta4, theta6, theta8;
396 if(!is_KannalaBrandt)
398 kud_px2 = kud * invpx * invpx;
399 kud_py2 = kud * invpy * invpy;
402 for (
unsigned int v = 0; v < height; v++) {
405 if(!is_KannalaBrandt)
406 fr1 = 1.0f + kud_py2 * deltav * deltav;
408 deltav_py = deltav * invpy;
410 for (
unsigned int u = 0; u < width; u++) {
413 if(!is_KannalaBrandt)
415 fr2 = fr1 + kud_px2 * deltau * deltau;
417 u_float = deltau * fr2 + u0;
418 v_float = deltav * fr2 + v0;
423 deltau_px = deltau * invpx;
429 theta6 = theta2 * theta4;
432 theta_d = theta * (1 + dist_coefs[0]*theta2 + dist_coefs[1]*theta4 +
433 dist_coefs[2]*theta6 + dist_coefs[3]*theta8);
436 scale = (std::fabs(r) < std::numeric_limits<double>::epsilon()) ? 1.0 : theta_d / r;
437 u_float =
static_cast<float>(deltau*scale + u0);
438 v_float =
static_cast<float>(deltav*scale + v0);
441 u_round =
static_cast<int>(u_float);
442 v_round =
static_cast<int>(v_float);
444 mapU[v][u] = u_round;
445 mapV[v][u] = v_round;
447 mapDu[v][u] = u_float - u_round;
448 mapDv[v][u] = v_float - v_round;
467 std::cerr <<
"Error, input image is empty." << std::endl;
474 for (
unsigned int i = 1; i < II.
getHeight(); i++) {
475 for (
unsigned int j = 1; j < II.
getWidth(); j++) {
476 II[i][j] = I[i - 1][j - 1] + II[i - 1][j] + II[i][j - 1] - II[i - 1][j - 1];
477 IIsq[i][j] =
vpMath::sqr(I[i - 1][j - 1]) + IIsq[i - 1][j] + IIsq[i][j - 1] - IIsq[i - 1][j - 1];
493 "image dimension mismatch between I1=%ux%u and I2=%ux%u",
504 SimdNormalizedCorrelation(I1.
bitmap, a, I2.
bitmap, b, I1.
getSize(), a2, b2, ab, useOptimized);
506 return ab / sqrt(a2 * b2);
520 for (
unsigned int i = 0; i < height; ++i)
521 for (
unsigned int j = 0; j < width; ++j)
523 for (
unsigned int j = 0; j < width; ++j)
534 for (
unsigned int i = 0; i < I.
getHeight(); ++i)
535 for (
unsigned int j = 0; j < I.
getWidth(); ++j)
536 I(i, j, I(i, j) / s);
553 int x1 = (int)floor(point.
get_i());
554 int x2 = (int)ceil(point.
get_i());
555 int y1 = (int)floor(point.
get_j());
556 int y2 = (int)ceil(point.
get_j());
562 v1 = (x2 - point.
get_i()) * I(x1, y1) + (point.
get_i() - x1) * I(x2, y1);
563 v2 = (x2 - point.
get_i()) * I(x1, y2) + (point.
get_i() - x1) * I(x2, y2);
567 return (y2 - point.
get_j()) * v1 + (point.
get_j() - y1) * v2;
571 "vpImageTools::interpolate(): bi-cubic interpolation is not implemented.");
593 for (
unsigned int x = 0; x < x_d; ++x) {
594 for (
unsigned int y = 0; y < y_d; ++y) {
616 for (
unsigned int x = 0; x < x_d; ++x) {
617 for (
unsigned int y = 0; y < y_d; ++y) {
643 std::cerr <<
"Error, input image is empty." << std::endl;
648 std::cerr <<
"Error, template image is empty." << std::endl;
653 std::cerr <<
"Error, template image is bigger than input image." << std::endl;
672 const double sum2 = (II_tpl[height_tpl][width_tpl] + II_tpl[0][0] - II_tpl[0][width_tpl] - II_tpl[height_tpl][0]);
673 const double mean2 = sum2 / I_tpl.
getSize();
674 for (
unsigned int cpt = 0; cpt < I_tpl_double.
getSize(); cpt++) {
675 I_tpl_double.
bitmap[cpt] -= mean2;
678 #if defined _OPENMP && _OPENMP >= 200711 // OpenMP 3.1 679 #pragma omp parallel for schedule(dynamic) 680 for (
unsigned int i = 0; i < I.
getHeight() - height_tpl; i += step_v) {
681 for (
unsigned int j = 0; j < I.
getWidth() - width_tpl; j += step_u) {
687 int end = (int)((I.
getHeight() - height_tpl) / step_v) + 1;
688 std::vector<unsigned int> vec_step_v((
size_t)end);
689 for (
unsigned int cpt = 0, idx = 0; cpt < I.
getHeight() - height_tpl; cpt += step_v, idx++) {
690 vec_step_v[(size_t)idx] = cpt;
692 #if defined _OPENMP // only to disable warning: ignoring #pragma omp parallel [-Wunknown-pragmas] 693 #pragma omp parallel for schedule(dynamic) 695 for (
int cpt = 0; cpt < end; cpt++) {
696 for (
unsigned int j = 0; j < I.
getWidth() - width_tpl; j += step_u) {
697 I_score[vec_step_v[cpt]][j] =
705 for (
unsigned int i = 0; i < I.
getHeight() - height_tpl; i += step_v) {
706 for (
unsigned int j = 0; j < I.
getWidth() - width_tpl; j += step_u) {
723 float vpImageTools::cubicHermite(
const float A,
const float B,
const float C,
const float D,
const float t)
725 float a = (-A + 3.0f * B - 3.0f * C + D) / 2.0f;
726 float b = A + 2.0f * C - (5.0f * B + D) / 2.0f;
727 float c = (-A + C) / 2.0f;
730 return a * t * t * t + b * t * t + c * t + d;
733 int vpImageTools::coordCast(
double x)
735 return x < 0 ? -1 :
static_cast<int>(x);
738 double vpImageTools::lerp(
double A,
double B,
double t) {
739 return A * (1.0 - t) + B * t;
742 float vpImageTools::lerp(
float A,
float B,
float t) {
743 return A * (1.0f - t) + B * t;
746 int64_t vpImageTools::lerp2(int64_t A, int64_t B, int64_t t, int64_t t_1) {
747 return A * t_1 + B * t;
753 unsigned int i0,
unsigned int j0)
760 (II[i0 + height_tpl][j0 + width_tpl] + II[i0][j0] - II[i0][j0 + width_tpl] - II[i0 + height_tpl][j0]);
761 const double sum2 = (II_tpl[height_tpl][width_tpl] + II_tpl[0][0] - II_tpl[0][width_tpl] - II_tpl[height_tpl][0]);
770 return ab / sqrt(a2 * b2);
788 #if defined _OPENMP // only to disable warning: ignoring #pragma omp parallel [-Wunknown-pragmas] 789 #pragma omp parallel for schedule(dynamic) 791 for (
int i_ = 0; i_ < static_cast<int>(I.
getHeight()); i_++) {
792 const unsigned int i =
static_cast<unsigned int>(i_);
793 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
795 int u_round = mapU[i][j];
796 int v_round = mapV[i][j];
798 float du = mapDu[i][j];
799 float dv = mapDv[i][j];
801 if (0 <= u_round && 0 <= v_round && u_round < static_cast<int>(I.
getWidth()) - 1
802 && v_round < static_cast<int>(I.
getHeight()) - 1) {
804 float col0 = lerp(I[v_round][u_round], I[v_round][u_round + 1], du);
805 float col1 = lerp(I[v_round + 1][u_round], I[v_round + 1][u_round + 1], du);
806 float value = lerp(col0, col1, dv);
808 Iundist[i][j] =
static_cast<unsigned char>(value);
831 #if defined _OPENMP // only to disable warning: ignoring #pragma omp parallel [-Wunknown-pragmas] 832 #pragma omp parallel for schedule(dynamic) 834 for (
int i = 0; i < static_cast<int>(I.
getHeight()); i++) {
836 mapDu.
data, mapDv.
data,
reinterpret_cast<unsigned char *
>(Iundist.
bitmap));
840 void vpImageTools::resizeSimdlib(
const vpImage<vpRGBa> &Isrc,
unsigned int resizeWidth,
844 Idst.
resize(resizeHeight, resizeWidth);
846 typedef Simd::View<Simd::Allocator> View;
850 Simd::Resize(src, dst, method ==
INTERPOLATION_LINEAR ? SimdResizeMethodBilinear : SimdResizeMethodArea);
857 Idst.
resize(resizeHeight, resizeWidth);
859 typedef Simd::View<Simd::Allocator> View;
863 Simd::Resize(src, dst, method ==
INTERPOLATION_LINEAR ? SimdResizeMethodBilinear : SimdResizeMethodArea);
866 bool vpImageTools::checkFixedPoint(
unsigned int x,
unsigned int y,
const vpMatrix &T,
bool affine)
868 double a0 = T[0][0];
double a1 = T[0][1];
double a2 = T[0][2];
869 double a3 = T[1][0];
double a4 = T[1][1];
double a5 = T[1][2];
870 double a6 = affine ? 0.0 : T[2][0];
871 double a7 = affine ? 0.0 : T[2][1];
872 double a8 = affine ? 1.0 : T[2][2];
874 double w = a6 * x + a7 * y + a8;
875 double x2 = (a0 * x + a1 * y + a2) / w;
876 double y2 = (a3 * x + a4 * y + a5) / w;
878 const double limit = 1 << 15;
Implementation of a matrix and operations on matrices.
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
vpCameraParametersProjType get_projModel() const
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
unsigned char B
Blue component.
Implementation of row vector and the associated operations.
Type * bitmap
points toward the bitmap
double getOrientation() const
Get the rectangle orientation (rad).
error that can be emited by ViSP classes.
Type * data
Address of the first element of the data array.
Implementation of a generic 2D array used as base class for matrices and vectors. ...
Error that can be emited by the vpImage class and its derivates.
unsigned char G
Green component.
static Type abs(const Type &x)
double getWidth() const
Get the rectangle width.
static double sqr(double x)
vpCameraParametersProjType
unsigned char A
Additionnal component.
Generic class defining intrinsic camera parameters.
std::vector< double > getKannalaBrandtDistortionCoefficients() const
Type getMeanValue() const
Return the mean value of the bitmap.
static int round(double x)
vpImagePoint getTopLeft() const
Get the top-left corner.
unsigned int getHeight() const
double getHeight() const
Get the rectangle height.
unsigned int getSize() const
unsigned char R
Red component.
Defines a rectangle in the plane.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
unsigned int getWidth() const
void resize(unsigned int i, bool flagNullify=true)
Defines an oriented rectangle in the plane.