39 #ifndef vpImageTools_H
40 #define vpImageTools_H
50 #include <visp3/core/vpImage.h>
52 #ifdef VISP_HAVE_PTHREAD
56 #include <visp3/core/vpImageException.h>
57 #include <visp3/core/vpMath.h>
58 #include <visp3/core/vpRect.h>
59 #include <visp3/core/vpCameraParameters.h>
81 unsigned int i_sub,
unsigned int j_sub,
82 unsigned int nrow_sub,
unsigned int ncol_sub,
92 Type threshold1, Type threshold2,
93 Type value1, Type value2, Type value3,
const bool useLUT=
false);
133 unsigned int i_sub,
unsigned int j_sub,
134 unsigned int nrow_sub,
unsigned int ncol_sub,
138 unsigned int imax = i_sub + nrow_sub ;
139 unsigned int jmax = j_sub + ncol_sub ;
144 nrow_sub = imax-i_sub ;
149 ncol_sub = jmax -j_sub ;
152 S.
resize(nrow_sub, ncol_sub) ;
153 for (i=i_sub ; i < imax ; i++)
154 for (j=j_sub ; j < jmax ; j++)
156 S[i-i_sub][j-j_sub] = I[i][j] ;
176 double dtop = rect.
getTop();
177 double dright = ceil( rect.
getRight() );
178 double dbottom = ceil( rect.
getBottom() );
180 if (dleft < 0.0) dleft = 0.0;
183 if (dright < 0.0) dright = 0.0;
186 if (dtop < 0.0) dtop = 0.0;
189 if (dbottom < 0.0) dbottom = 0.0;
193 unsigned int left = (
unsigned int) dleft;
194 unsigned int top = (
unsigned int) dtop;
195 unsigned int bottom = (
unsigned int) dbottom;
196 unsigned int right = (
unsigned int) dright;
198 unsigned int width = right - left + 1;;
199 unsigned int height = bottom - top + 1;
202 for (
unsigned int i=top ; i <= bottom ; i++) {
203 for (
unsigned int j=left ; j <= right ; j++) {
204 S[i-top][j-left] = I[i][j] ;
223 Type threshold1, Type threshold2,
224 Type value1, Type value2, Type value3,
const bool useLUT)
227 std::cerr <<
"LUT not available for this type ! Will use the iteration method." << std::endl;
233 for (; p < pend; p ++) {
235 if (v < threshold1) *p = value1;
236 else if (v > threshold2) *p = value3;
255 unsigned char threshold1,
unsigned char threshold2,
256 unsigned char value1,
unsigned char value2,
unsigned char value3,
const bool useLUT)
260 unsigned char lut[256];
261 for(
unsigned int i = 0; i < 256; i++) {
262 lut[i] = i < threshold1 ? value1 : (i > threshold2 ? value3 : value2);
268 unsigned char *p = I.
bitmap;
270 for (; p < pend; p ++) {
272 if (v < threshold1) *p = value1;
273 else if (v > threshold2) *p = value3;
279 #ifdef VISP_HAVE_PTHREAD
281 #ifndef DOXYGEN_SHOULD_SKIP_THIS
283 class vpUndistortInternalType
291 unsigned int nthreads;
292 unsigned int threadid;
294 vpUndistortInternalType()
295 : src(NULL), dst(NULL), width(0), height(0), cam(), nthreads(0), threadid(0)
298 vpUndistortInternalType(
const vpUndistortInternalType<Type> &u) {
301 vpUndistortInternalType &operator=(
const vpUndistortInternalType<Type> &u) {
307 nthreads = u.nthreads;
308 threadid = u.threadid;
311 static void *vpUndistort_threaded(
void *arg);
316 void *vpUndistortInternalType<Type>::vpUndistort_threaded(
void *arg)
318 vpUndistortInternalType<Type> *undistortSharedData = (vpUndistortInternalType<Type>*)arg;
319 int offset = (int)undistortSharedData->threadid;
320 int width = (
int)undistortSharedData->width;
321 int height = (int)undistortSharedData->height;
322 int nthreads = (
int)undistortSharedData->nthreads;
324 double u0 = undistortSharedData->cam.get_u0();
325 double v0 = undistortSharedData->cam.get_v0();
326 double px = undistortSharedData->cam.get_px();
327 double py = undistortSharedData->cam.get_py();
328 double kud = undistortSharedData->cam.get_kud();
330 double invpx = 1.0/px;
331 double invpy = 1.0/py;
333 double kud_px2 = kud * invpx * invpx;
334 double kud_py2 = kud * invpy * invpy;
336 Type *dst = undistortSharedData->dst+(height/nthreads*offset)*width;
337 Type *src = undistortSharedData->src;
339 for (
double v = height/nthreads*offset;v < height/nthreads*(offset+1) ; v++) {
340 double deltav = v - v0;
342 double fr1 = 1.0 + kud_py2 * deltav * deltav;
344 for (
double u = 0 ; u < width ; u++) {
346 double deltau = u - u0;
348 double fr2 = fr1 + kud_px2 * deltau * deltau;
350 double u_double = deltau * fr2 + u0;
351 double v_double = deltav * fr2 + v0;
356 int u_round = (int) (u_double);
357 int v_round = (int) (v_double);
358 if (u_round < 0.f) u_round = -1;
359 if (v_round < 0.f) v_round = -1;
360 double du_double = (u_double) - (
double) u_round;
361 double dv_double = (v_double) - (
double) v_round;
364 if ( (0 <= u_round) && (0 <= v_round) &&
365 (u_round < ((width) - 1)) && (v_round < ((height) - 1)) ) {
367 const Type* _mp = &src[v_round*width+u_round];
368 v01 = (Type)(_mp[0] + ((_mp[1] - _mp[0]) * du_double));
370 v23 = (Type)(_mp[0] + ((_mp[1] - _mp[0]) * du_double));
371 *dst = (Type)(v01 + ((v23 - v01) * dv_double));
380 pthread_exit((
void*) 0);
383 #endif // DOXYGEN_SHOULD_SKIP_THIS
384 #endif // VISP_HAVE_PTHREAD
410 #ifdef VISP_HAVE_PTHREAD
417 undistI.
resize(height, width);
422 if (std::fabs(kud) <= std::numeric_limits<double>::epsilon()) {
428 unsigned int nthreads = 2;
430 pthread_t *callThd =
new pthread_t [nthreads];
431 pthread_attr_init(&attr);
432 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
434 vpUndistortInternalType<Type> *undistortSharedData;
435 undistortSharedData =
new vpUndistortInternalType<Type> [nthreads];
437 for(
unsigned int i=0;i<nthreads;i++) {
440 undistortSharedData[i].src = I.
bitmap;
441 undistortSharedData[i].dst = undistI.
bitmap;
442 undistortSharedData[i].width = I.
getWidth();
443 undistortSharedData[i].height = I.
getHeight();
444 undistortSharedData[i].cam = cam;
445 undistortSharedData[i].nthreads = nthreads;
446 undistortSharedData[i].threadid = i;
447 pthread_create( &callThd[i], &attr,
448 &vpUndistortInternalType<Type>::vpUndistort_threaded,
449 &undistortSharedData[i]);
451 pthread_attr_destroy(&attr);
454 for(
unsigned int i=0;i<nthreads;i++) {
456 pthread_join( callThd[i], NULL);
460 delete [] undistortSharedData;
461 #else // VISP_HAVE_PTHREAD
468 undistI.
resize(height, width);
477 if (std::fabs(kud) <= std::numeric_limits<double>::epsilon()) {
483 double invpx = 1.0/px;
484 double invpy = 1.0/py;
486 double kud_px2 = kud * invpx * invpx;
487 double kud_py2 = kud * invpy * invpy;
489 Type *dst = undistI.
bitmap;
490 for (
double v = 0;v < height ; v++) {
491 double deltav = v - v0;
493 double fr1 = 1.0 + kud_py2 * deltav * deltav;
495 for (
double u = 0 ; u < width ; u++) {
497 double deltau = u - u0;
499 double fr2 = fr1 + kud_px2 * deltau * deltau;
501 double u_double = deltau * fr2 + u0;
502 double v_double = deltav * fr2 + v0;
509 int u_round = (int) (u_double);
510 int v_round = (int) (v_double);
511 if (u_round < 0.f) u_round = -1;
512 if (v_round < 0.f) v_round = -1;
513 double du_double = (u_double) - (
double) u_round;
514 double dv_double = (v_double) - (
double) v_round;
517 if ( (0 <= u_round) && (0 <= v_round) &&
518 (u_round < (((
int)width) - 1)) && (v_round < (((
int)height) - 1)) ) {
520 const Type* _mp = &I[(
unsigned int)v_round][(
unsigned int)u_round];
521 v01 = (Type)(_mp[0] + ((_mp[1] - _mp[0]) * du_double));
523 v23 = (Type)(_mp[0] + ((_mp[1] - _mp[0]) * du_double));
524 *dst = (Type)(v01 + ((v23 - v01) * dv_double));
533 #endif // VISP_HAVE_PTHREAD
543 undistI.
resize(height,width);
557 for(
int v = 0 ; v < height; v++){
558 for(
int u = 0; u < height; u++){
561 double u_double = ((double)u - u0)*(1.0+kd*r2) + u0;
562 double v_double = ((double)v - v0)*(1.0+kd*r2) + v0;
563 undistI[v][u] = I.getPixelBI((
float)u_double,(
float)v_double);
580 unsigned int height = 0, width = 0;
584 newI.
resize(height, width);
586 for (
unsigned int i = 0; i < height; i++)
588 memcpy(newI.
bitmap+i*width, I.
bitmap+(height-1-i)*width,
627 unsigned int height = 0, width = 0;
635 for ( i = 0; i < height/2; i++)
unsigned int getWidth() const
Type * bitmap
points toward the bitmap
void performLut(const Type(&lut)[256])
static double sqr(double x)
Generic class defining intrinsic camera parameters.
void resize(const unsigned int h, const unsigned int w)
set the size of the image without initializing it.
unsigned int getHeight() const
Defines a rectangle in the plane.
Definition of the vpImage class member functions.