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)
unsigned int getWidth() 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
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. ...
double getHeight() const
Get the rectangle height.
Error that can be emited by the vpImage class and its derivates.
unsigned char G
Green component.
double getWidth() const
Get the rectangle width.
static Type abs(const Type &x)
double getOrientation() const
Get the rectangle orientation (rad).
unsigned int getSize() const
static double sqr(double x)
vpCameraParametersProjType
unsigned char A
Additionnal component.
Generic class defining intrinsic camera parameters.
std::vector< double > getKannalaBrandtDistortionCoefficients() const
static int round(double x)
vpCameraParametersProjType get_projModel() const
vpImagePoint getTopLeft() const
Get the top-left corner.
unsigned char R
Red component.
Type getMeanValue() const
Return the mean value of the bitmap.
unsigned int getHeight() const
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 ...
void resize(unsigned int i, bool flagNullify=true)
Defines an oriented rectangle in the plane.