43 #ifndef vpImageTools_H
44 #define vpImageTools_H
54 #include <visp/vpImage.h>
56 #ifdef VISP_HAVE_PTHREAD
60 #include <visp/vpImageException.h>
61 #include <visp/vpMath.h>
62 #include <visp/vpRect.h>
63 #include <visp/vpCameraParameters.h>
85 unsigned int i_sub,
unsigned int j_sub,
86 unsigned int nrow_sub,
unsigned int ncol_sub,
95 Type threshold1, Type threshold2,
96 Type value1, Type value2, Type value3);
134 unsigned int i_sub,
unsigned int j_sub,
135 unsigned int nrow_sub,
unsigned int ncol_sub,
139 unsigned int imax = i_sub + nrow_sub ;
140 unsigned int jmax = j_sub + ncol_sub ;
145 nrow_sub = imax-i_sub ;
150 ncol_sub = jmax -j_sub ;
153 S.
resize(nrow_sub, ncol_sub) ;
154 for (i=i_sub ; i < imax ; i++)
155 for (j=j_sub ; j < jmax ; j++)
157 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] ;
222 Type threshold1, Type threshold2,
223 Type value1, Type value2, Type value3)
226 unsigned char *p = I.
bitmap;
228 for (; p < pend; p ++) {
230 if (v < threshold1) *p = value1;
231 else if (v > threshold2) *p = value3;
237 #ifdef VISP_HAVE_PTHREAD
239 #ifndef DOXYGEN_SHOULD_SKIP_THIS
241 class vpUndistortInternalType
249 unsigned int nthreads;
250 unsigned int threadid;
252 vpUndistortInternalType() {
255 nthreads = threadid = 0;
257 vpUndistortInternalType(
const vpUndistortInternalType<Type> &u) {
263 nthreads = u.nthreads;
264 threadid = u.threadid;
267 static void *vpUndistort_threaded(
void *arg);
272 void *vpUndistortInternalType<Type>::vpUndistort_threaded(
void *arg)
274 vpUndistortInternalType<Type> *undistortSharedData = (vpUndistortInternalType<Type>*)arg;
275 int offset = (int)undistortSharedData->threadid;
276 int width = (
int)undistortSharedData->width;
277 int height = (int)undistortSharedData->height;
278 int nthreads = (
int)undistortSharedData->nthreads;
280 double u0 = undistortSharedData->cam.get_u0();
281 double v0 = undistortSharedData->cam.get_v0();
282 double px = undistortSharedData->cam.get_px();
283 double py = undistortSharedData->cam.get_py();
284 double kud = undistortSharedData->cam.get_kud();
286 double invpx = 1.0/px;
287 double invpy = 1.0/py;
289 double kud_px2 = kud * invpx * invpx;
290 double kud_py2 = kud * invpy * invpy;
292 Type *dst = undistortSharedData->dst+(height/nthreads*offset)*width;
293 Type *src = undistortSharedData->src;
295 for (
double v = height/nthreads*offset;v < height/nthreads*(offset+1) ; v++) {
296 double deltav = v - v0;
298 double fr1 = 1.0 + kud_py2 * deltav * deltav;
300 for (
double u = 0 ; u < width ; u++) {
302 double deltau = u - u0;
304 double fr2 = fr1 + kud_px2 * deltau * deltau;
306 double u_double = deltau * fr2 + u0;
307 double v_double = deltav * fr2 + v0;
312 int u_round = (int) (u_double);
313 int v_round = (int) (v_double);
314 if (u_round < 0.f) u_round = -1;
315 if (v_round < 0.f) v_round = -1;
316 double du_double = (u_double) - (
double) u_round;
317 double dv_double = (v_double) - (
double) v_round;
320 if ( (0 <= u_round) && (0 <= v_round) &&
321 (u_round < ((width) - 1)) && (v_round < ((height) - 1)) ) {
323 const Type* _mp = &src[v_round*width+u_round];
324 v01 = (Type)(_mp[0] + ((_mp[1] - _mp[0]) * du_double));
326 v23 = (Type)(_mp[0] + ((_mp[1] - _mp[0]) * du_double));
327 *dst = (Type)(v01 + ((v23 - v01) * dv_double));
336 pthread_exit((
void*) 0);
339 #endif // DOXYGEN_SHOULD_SKIP_THIS
340 #endif // VISP_HAVE_PTHREAD
366 #ifdef VISP_HAVE_PTHREAD
373 undistI.
resize(height, width);
378 if (std::fabs(kud) <= std::numeric_limits<double>::epsilon()) {
384 unsigned int nthreads = 2;
386 pthread_t *callThd =
new pthread_t [nthreads];
387 pthread_attr_init(&attr);
388 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
390 vpUndistortInternalType<Type> *undistortSharedData;
391 undistortSharedData =
new vpUndistortInternalType<Type> [nthreads];
393 for(
unsigned int i=0;i<nthreads;i++) {
396 undistortSharedData[i].src = I.
bitmap;
397 undistortSharedData[i].dst = undistI.
bitmap;
398 undistortSharedData[i].width = I.
getWidth();
399 undistortSharedData[i].height = I.
getHeight();
400 undistortSharedData[i].cam = cam;
401 undistortSharedData[i].nthreads = nthreads;
402 undistortSharedData[i].threadid = i;
403 pthread_create( &callThd[i], &attr,
404 &vpUndistortInternalType<Type>::vpUndistort_threaded,
405 &undistortSharedData[i]);
407 pthread_attr_destroy(&attr);
410 for(
unsigned int i=0;i<nthreads;i++) {
412 pthread_join( callThd[i], NULL);
416 delete [] undistortSharedData;
417 #else // VISP_HAVE_PTHREAD
424 undistI.
resize(height, width);
433 if (std::fabs(kud) <= std::numeric_limits<double>::epsilon()) {
439 double invpx = 1.0/px;
440 double invpy = 1.0/py;
442 double kud_px2 = kud * invpx * invpx;
443 double kud_py2 = kud * invpy * invpy;
445 Type *dst = undistI.
bitmap;
446 for (
double v = 0;v < height ; v++) {
447 double deltav = v - v0;
449 double fr1 = 1.0 + kud_py2 * deltav * deltav;
451 for (
double u = 0 ; u < width ; u++) {
453 double deltau = u - u0;
455 double fr2 = fr1 + kud_px2 * deltau * deltau;
457 double u_double = deltau * fr2 + u0;
458 double v_double = deltav * fr2 + v0;
465 int u_round = (int) (u_double);
466 int v_round = (int) (v_double);
467 if (u_round < 0.f) u_round = -1;
468 if (v_round < 0.f) v_round = -1;
469 double du_double = (u_double) - (
double) u_round;
470 double dv_double = (v_double) - (
double) v_round;
473 if ( (0 <= u_round) && (0 <= v_round) &&
474 (u_round < (((
int)width) - 1)) && (v_round < (((
int)height) - 1)) ) {
476 const Type* _mp = &I[(
unsigned int)v_round][(
unsigned int)u_round];
477 v01 = (Type)(_mp[0] + ((_mp[1] - _mp[0]) * du_double));
479 v23 = (Type)(_mp[0] + ((_mp[1] - _mp[0]) * du_double));
480 *dst = (Type)(v01 + ((v23 - v01) * dv_double));
489 #endif // VISP_HAVE_PTHREAD
499 undistI.
resize(height,width);
513 for(
int v = 0 ; v < height; v++){
514 for(
int u = 0; u < height; u++){
517 double u_double = ((double)u - u0)*(1.0+kd*r2) + u0;
518 double v_double = ((double)v - v0)*(1.0+kd*r2) + v0;
519 undistI[v][u] = I.getPixelBI((
float)u_double,(
float)v_double);
536 unsigned int height = 0, width = 0;
541 newI.
resize(height, width);
543 for ( i = 0; i < height; i++)
545 memcpy(newI.
bitmap+i*width, I.
bitmap+(height-1-i)*width,
584 unsigned int height = 0, width = 0;
592 for ( i = 0; i < height/2; i++)
unsigned int getWidth() const
Type * bitmap
points toward the bitmap
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
unsigned int getHeight() const
Defines a rectangle in the plane.
Definition of the vpImage class member functions.