#include #include #include #include #include //VideoCapture #include //cvtColor /* Compute Mean Square Error - fast version */ double computeMSE(const cv::Mat &m1, const cv::Mat &m2) { assert(m1.size() == m2.size() && m1.type() == m2.type() && m1.type() == CV_8UC1); unsigned long sum = 0; int rows = m1.rows; int cols = m1.cols; if (m1.isContinuous() && m2.isContinuous()) { cols *= rows; rows = 1; } for (int y = 0; y < rows; ++y) { const unsigned char *p1 = m1.ptr(y); const unsigned char *p2 = m2.ptr(y); for(int x = 0; x < cols; ++x) { const int diff = p1[x]-p2[x]; sum += diff * diff; } } const double MSE = sum / (double)(m1.rows*m1.cols); return MSE; } /* Compute Peak Signal-to-Noise Ratio */ double computePSNR(double MSE) { const double PSNR = 10 * log10(255*255 / MSE); return PSNR; } /* Compute Entropy - fast version */ double computeEntropy(cv::Mat m) { assert(m.type() == CV_8UC1); const int size = 256; long histogram[size] = {0}; int rows = m.rows; int cols = m.cols; if (m.isContinuous()) { cols *= rows; rows = 1; } for (int i = 0; i < rows; ++i) { const unsigned char *p = m.ptr(i); for(int j = 0; j < cols; ++j) { histogram[p[j]] += 1; } } const double norm = 1. /(double)(rows*cols); double entropy = 0.0; for (int i=0; i 0) { const double pi = (histogram[i]) * norm; entropy -= pi * log2(pi); } } return entropy; } /* Compute Error Image - faster version */ void computeErrorImage(const cv::Mat &im, const cv::Mat &imC, cv::Mat &imErr) { assert(im.cols == imC.cols && im.rows == imC.rows && im.type() == CV_8UC1 && imC.type() == CV_8UC1); imErr.create(im.rows, im.cols, CV_8UC1); //nothing done if matrix already has the desired size int rows = im.rows; int cols = im.cols; if (im.isContinuous() && imC.isContinuous() && imErr.isContinuous()) { cols *= rows; rows = 1; } for (int y = 0; y < rows; ++y) { const unsigned char *p1 = im.ptr(y); const unsigned char *p2 = imC.ptr(y); unsigned char *pe = imErr.ptr(y); for(int x = 0; x < cols; ++x) { pe[x] = cv::saturate_cast(p1[x]-p2[x] + 128); } } } void computeMotionVectorsWithFullSearch(const cv::Mat &m1, const cv::Mat &m2, int blockSize, int windowSize, cv::Mat &motionVectors) { //TODO //The output is in parameter: motionVectors. } void compensateImage(const cv::Mat &motionVectors, const cv::Mat &prev, cv::Mat &compensated) { //TODO //The output is in parameter: compensated. } /* Draw one vector between two points */ void drawMV(cv::Mat &img, const cv::Point &pt1, const cv::Point &pt2, const cv::Scalar &color, const int thickness) { cv::Point p1 = pt1; cv::Point p2 = pt2; #if 1 const double angle = atan2( (double) p1.y - p2.y, (double) p1.x - p2.x ); //const double hypotenuse = sqrt( SQUARE(p1.y - p2.y) + SQUARE(p1.x - p2.x) ); cv::line(img, p1, p2, color, thickness, CV_AA, 0); const double scaling_factor = 2; p1.x = (int) (p2.x + scaling_factor * cos(angle + M_PI / 4)); p1.y = (int) (p2.y + scaling_factor * sin(angle + M_PI / 4)); cv::line(img, p1, p2, color, thickness, CV_AA, 0); p1.x = (int) (p2.x + scaling_factor * cos(angle - M_PI / 4)); p1.y = (int) (p2.y + scaling_factor * sin(angle - M_PI / 4)); cv::line(img, p1, p2, color, thickness, CV_AA, 0); #else cv::line(img, p1, p2, color, thickness, CV_AA, 0); //cv::circle(img, p1, 2, color, -1); cv::circle(img, p2, 2, color, -1); #endif } /* Draw Motion Vectors */ template void drawMV(cv::Mat &img, const cv::Mat &motionVectors, int step, const cv::Scalar &color, const int thickness) { const int blockSize = img.rows / motionVectors.rows; const int halfBlockSize = blockSize / 2 ; const int nbY = img.rows / blockSize; const int nbX = img.cols / blockSize; assert(nbX == motionVectors.cols); assert(nbY == motionVectors.rows); for(int y = 0; y < nbY; y+=step) { const T *p = motionVectors.ptr(y); for(int x = 0; x < nbX; x+=step) { const float mv_x = (p[x])[0]; const float mv_y = (p[x])[1]; size_t x1 = x * blockSize + halfBlockSize; size_t y1 = y * blockSize + halfBlockSize; size_t x2 = x1 + mv_x; size_t y2 = y1 + mv_y; const cv::Point p1 = cv::Point2i(x1, y1); const cv::Point p2 = cv::Point2i(x2, y2); drawMV(img, p2, p1, color, thickness); } } } /* Draw Motion Vectors from CV_32SC2 matrix. */ void drawMV_i(cv::Mat &img, const cv::Mat &motionVectors, int step, const cv::Scalar &color, const int thickness) { assert(motionVectors.type() == CV_32SC2); drawMV(img, motionVectors, step, color, thickness); } /* Draw Motion Vectors from CV_32FC2 matrix. */ void drawMV_f(cv::Mat &img, const cv::Mat &motionVectors, int step, const cv::Scalar &color, const int thickness) { assert(motionVectors.type() == CV_32FC2); drawMV(img, motionVectors, step, color, thickness); } int main(int argc, char **argv) { //TODO //take parameters: videoFilename deltaT blockSize windowSize //... return EXIT_SUCCESS; }