int checkCompareImg(VSMotionDetect* md, const VSFrame* frame){ int i; int error; uint8_t *Y_c; Field field; field.x=400; field.y=400; field.size=12; Y_c = frame->data[0]; int linesize = frame->linesize[0]; for(i=-10;i<10; i+=2){ printf("\nCheck: shiftX = %i\n",i); error = compareSubImg(Y_c, Y_c, &field, linesize, linesize, md->fi.height, 1, i, 0, INT_MAX); fprintf(stderr,"mismatch %i: %i\n", i, error); } return 1; }
/* calculates the optimal transformation for one field in RGB * slower than the YUV version because it uses all three color channels */ Transform calcFieldTransRGB(MotionDetect* md, const Field* field, int fieldnum) { int tx = 0; int ty = 0; uint8_t *I_c = md->curr, *I_p = md->prev; int i, j; int bpp = (md->fi.pFormat == PF_RGB) ?3 :4; /* Here we improve speed by checking first the most probable position then the search paths are most effectively cut. (0,0) is a simple start */ unsigned int minerror = compareSubImg(I_c, I_p, field, md->fi.width, md->fi.height, bpp, 0, 0, UINT_MAX); // check all positions... for (i = -md->maxShift; i <= md->maxShift; i += md->stepSize) { for (j = -md->maxShift; j <= md->maxShift; j += md->stepSize) { if (i == 0 && j == 0) continue; //no need to check this since already done unsigned int error = compareSubImg(I_c, I_p, field, md->fi.width, md->fi.height, bpp, i, j, minerror); if (error < minerror) { minerror = error; tx = i; ty = j; } } } if (md->stepSize > 1) { // make fine grain check around the best match int txc = tx; // save the shifts int tyc = ty; int r = md->stepSize - 1; for (i = txc - r; i <= txc + r; i += 1) { for (j = tyc - r; j <= tyc + r; j += 1) { if (i == txc && j == tyc) continue; //no need to check this since already done unsigned int error = compareSubImg(I_c, I_p, field, md->fi.width, md->fi.height, bpp, i, j, minerror); if (error < minerror) { minerror = error; tx = i; ty = j; } } } } if (!md->allowMax && fabs(tx) >= md->maxShift + md->stepSize) { #ifdef STABVERBOSE ds_log_msg(md->modName, "maximal x shift "); #endif tx = 0; } if (!md->allowMax && fabs(ty) == md->maxShift + md->stepSize) { #ifdef STABVERBOSE ds_log_msg(md->modName, "maximal y shift "); #endif ty = 0; } Transform t = null_transform(); t.x = tx; t.y = ty; return t; }
/* calculates the optimal transformation for one field in YUV frames * (only luminance) */ Transform calcFieldTransYUV(MotionDetect* md, const Field* field, int fieldnum) { int tx = 0; int ty = 0; uint8_t *Y_c = md->curr, *Y_p = md->prev; // we only use the luminance part of the image int i, j; int stepSize = md->stepSize; #ifdef STABVERBOSE // printf("%i %i %f\n", md->frameNum, fieldnum, contr); FILE *f = NULL; char buffer[32]; ds_snprintf(buffer, sizeof(buffer), "f%04i_%02i.dat", md->frameNum, fieldnum); f = fopen(buffer, "w"); fprintf(f, "# splot \"%s\"\n", buffer); #endif #ifdef USE_SPIRAL_FIELD_CALC unsigned int minerror = UINT_MAX; // check all positions by outgoing spiral i = 0; j = 0; int limit = 1; int step = 0; int dir = 0; while (j >= -md->maxShift && j <= md->maxShift && i >= -md->maxShift && i <= md->maxShift) { unsigned int error = compareSubImg(Y_c, Y_p, field, md->fi.width, md->fi.height, 1, i, j, minerror); if (error < minerror) { minerror = error; tx = i; ty = j; } //spiral indexing... step++; switch (dir) { case 0: i += stepSize; if (step == limit) { dir = 1; step = 0; } break; case 1: j += stepSize; if (step == limit) { dir = 2; step = 0; limit++; } break; case 2: i -= stepSize; if (step == limit) { dir = 3; step = 0; } break; case 3: j -= stepSize; if (step == limit) { dir = 0; step = 0; limit++; } break; } } #else /* Here we improve speed by checking first the most probable position then the search paths are most effectively cut. (0,0) is a simple start */ unsigned int minerror = compareSubImg(Y_c, Y_p, field, md->fi.width, md->fi.height, 1, 0, 0, UINT_MAX); // check all positions... for (i = -md->maxShift; i <= md->maxShift; i += stepSize) { for (j = -md->maxShift; j <= md->maxShift; j += stepSize) { if( i==0 && j==0 ) continue; //no need to check this since already done unsigned int error = compareSubImg(Y_c, Y_p, field, md->fi.width, md->fi.height, 1, i, j, minerror); if (error < minerror) { minerror = error; tx = i; ty = j; } #ifdef STABVERBOSE fprintf(f, "%i %i %f\n", i, j, error); #endif } } #endif while(stepSize > 1) {// make fine grain check around the best match int txc = tx; // save the shifts int tyc = ty; int newStepSize = stepSize/2; int r = stepSize - newStepSize; for (i = txc - r; i <= txc + r; i += newStepSize) { for (j = tyc - r; j <= tyc + r; j += newStepSize) { if (i == txc && j == tyc) continue; //no need to check this since already done unsigned int error = compareSubImg(Y_c, Y_p, field, md->fi.width, md->fi.height, 1, i, j, minerror); #ifdef STABVERBOSE fprintf(f, "%i %i %f\n", i, j, error); #endif if (error < minerror) { minerror = error; tx = i; ty = j; } } } stepSize /= 2; } #ifdef STABVERBOSE fclose(f); ds_log_msg(md->modName, "Minerror: %f\n", minerror); #endif if (!md->allowMax && fabs(tx) >= md->maxShift + md->stepSize) { #ifdef STABVERBOSE ds_log_msg(md->modName, "maximal x shift "); #endif tx = 0; } if (!md->allowMax && fabs(ty) == md->maxShift + md->stepSize) { #ifdef STABVERBOSE ds_log_msg(md->modName, "maximal y shift "); #endif ty = 0; } Transform t = null_transform(); t.x = tx; t.y = ty; return t; }