I am trying to implement a tool change algorithm for tracking objects and have reviewed related concepts.
Now I was able to successfully generate the reverse stream from my camera using the hue roi single-channel histogram and a single-channel video stream that seems great, I know that there is a return function in the opencv library, but I'm trying to implement it myself using data structures, presented in opencv, calculating the moments and calculating the average centroid of the search box.
But for some reason I cannot find the problem in my code, as it continues to converge in the upper left corner of my video stream for any input roi (region of interest) that needs to be tracked. The following is a snippet of the function code for calculating the center of gravity of the search box, where I feel the problem lies, but not sure what it is, I would really appreciate it if someone could point me in the right direction:
void moment(Mat &backproj, Rect &win){
int x_c, y_c, x_c_new, y_c_new;
int idx_row, idx_col;
double m00 = 0.0 , m01 = 0.0 , m10 = 0.0 ;
double res = 1.0, TOL = 0.003 ;
y_c = (int) backproj.rows / 2 ;
x_c = (int) backproj.cols / 2 ;
while (res > TOL){
win.width = (int) 80;
win.height = (int) 60;
win.x = (int) (x_c - win.width / 2) ;
win.y = (int) (y_c - win.height / 2);
if (win.x < 0)
win.x = win.x % backproj.cols + backproj.cols ;
if (win.y < 0)
win.y = win.y % backproj.rows + backproj.rows ;
for (int i = 0; i < win.height; i++ ){
idx_row = (win.y + i) % (int)backproj.rows ;
for (int j = 0; j < win.width; j++ ){
idx_col = (win.x + j) % (int)backproj.cols ;
m00 += (double) backproj.at<uchar>(idx_row, idx_col) ;
m10 += (double) backproj.at<uchar>(idx_row, idx_col) * i ;
m01 += (double) backproj.at<uchar>(idx_row, idx_col) * j ;
}
}
x_c_new = (int) ( m10 / m00 ) ;
y_c_new = (int) ( m01 / m00 );
res = sqrt( pow((x_c_new - x_c), 2.0) + pow((y_c_new - y_c), 2.0) ) ;
x_c = x_c_new;
y_c = y_c_new;
}
}
This is my second stackoverflow request, so please excuse me for any recommendations I forgot to follow.
EDIT
modified m00, m01, m10 to block level variables inside WHILE-LOOP instead of function level variables, thanks to Daniel Strul, specifying it, but the problem still remains. Now the search box jumps around the borders of the frame, and does not focus on roi.
void moment(Mat &backproj, Rect &win){
int x_c, y_c, x_c_new, y_c_new;
int idx_row, idx_col;
double m00 , m01 , m10 ;
double res = 1.0, TOL = 0.003 ;
y_c = (int) backproj.rows / 2 ;
x_c = (int) backproj.cols / 2 ;
while (res > TOL){
m00 = 0.0 , m01 = 0.0 , m10 = 0.0
win.width = (int) 80;
win.height = (int) 60;
win.x = (int) (x_c - win.width / 2) ;
win.y = (int) (y_c - win.height / 2);
if (win.x < 0)
win.x = win.x % backproj.cols + backproj.cols ;
if (win.y < 0)
win.y = win.y % backproj.rows + backproj.rows ;
for (int i = 0; i < win.height; i++ ){
idx_row = (win.y + i) % (int)backproj.rows ;
for (int j = 0; j < win.width; j++ ){
idx_col = (win.x + j) % (int)backproj.cols ;
m00 += (double) backproj.at<uchar>(idx_row, idx_col) ;
m10 += (double) backproj.at<uchar>(idx_row, idx_col) * i ;
m01 += (double) backproj.at<uchar>(idx_row, idx_col) * j ;
}
}
x_c_new = (int) ( m10 / m00 ) ;
y_c_new = (int) ( m01 / m00 );
res = sqrt( pow((x_c_new - x_c), 2.0) + pow((y_c_new - y_c), 2.0) ) ;
x_c = x_c_new;
y_c = y_c_new;
}
}