Skip to content

Instantly share code, notes, and snippets.

@nvnhat95
Last active December 12, 2016 16:17
Show Gist options
  • Save nvnhat95/9922f4b49ff2288228ad598268729c74 to your computer and use it in GitHub Desktop.
Save nvnhat95/9922f4b49ff2288228ad598268729c74 to your computer and use it in GitHub Desktop.
#include <opencv\cv.h>
#include <opencv\highgui.h>
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
// display video from array of frames, using left and right button.
void displayVideo(cv::Mat* frames, cv::Point2i* centralPoints, int numFrame, int FPS, string windowName) {
double prevTick = cv::getTickCount();
double currentTick;
double Tickfrequency = cv::getTickFrequency();
double waitTick = (1.0 / FPS) * Tickfrequency;
int cntFrame = -1;
int x, y;
int step = frames[0].step;
while (1) {
int k = cv::waitKey(30);
if (k != -1) cout << centralPoints[cntFrame].x << " " << centralPoints[cntFrame].y << endl;
if (k == 2555904) { // handle right button pressed event
cntFrame = min(cntFrame + 1, numFrame - 1);
int xx = centralPoints[cntFrame].x;
int yy = centralPoints[cntFrame].y;
// display cent point (9 pixels).
for (int i = -2; i <= 2; ++i) for (int j = -2; j <= 2; ++j) {
x = xx + i; y = yy + j;
frames[cntFrame].data[y * step + x] = 255;
}
cv::imshow(windowName, frames[cntFrame]);
}
if (k == 2424832) { //handle left button pressed event
cntFrame = max(0, cntFrame - 1);
int xx = centralPoints[cntFrame].x;
int yy = centralPoints[cntFrame].y;
// display cent point (9 pixels).
for (int i = -2; i <= 2; ++i) for (int j = -2; j <= 2; ++j) {
x = xx + i; y = yy + j;
frames[cntFrame].data[y * step + x] = 255;
}
cv::imshow(windowName, frames[cntFrame]);
}
if (k == 27) break;
}
}
void openVideoFromFile(string filename, int margin) {
cv::VideoCapture cap(filename);
if(!cap.isOpened()) {
cout << "can't open " << filename;
return;
}
// print video information
int height = cap.get(CV_CAP_PROP_FRAME_HEIGHT), width = cap.get(CV_CAP_PROP_FRAME_WIDTH);
cout << height << " x " << width << endl;
int totalFrame = cap.get(CV_CAP_PROP_FRAME_COUNT);
cout << totalFrame << " frames" << endl;
int fps = cap.get(CV_CAP_PROP_FPS);
cout << fps << " FPS" << endl;
cv::Mat* frames = new cv::Mat[totalFrame];
cv::Point2i* centPoints = new cv::Point2i[totalFrame];
cv::Mat frame;
cv::namedWindow(filename, 1);
cv::resizeWindow(filename, width, height);
int cntFrame = 0;
while (cap.read(frame)) {
cv::cvtColor(frame, frame, CV_RGB2GRAY);
cv::Rect roi(margin, frame.rows / 4 * 3, frame.cols - margin * 2, frame.rows / 4);
cv::Mat cropped = frame(roi); // crop 1/4 bottom of video
cv::GaussianBlur(cropped, cropped, cv::Size(3, 11), 1);
cv::medianBlur(cropped, cropped, 7);
//cv::Canny(cropped, cropped, 0, 50, 3);
// find max and min, then stretch image with log and exp
double minVal;
double maxVal;
minMaxLoc(cropped, &minVal, &maxVal);
cout << "min val : " << minVal << " max val: " << maxVal << endl;
int t;
double lg = log(maxVal);
for (int i = 0; i < cropped.rows; ++i) {
for (int j = 0; j < cropped.cols; ++j) {
t = cropped.data[i * cropped.step + j];
cropped.data[i * cropped.step + j] = exp((double)(t - minVal) / (maxVal - minVal) * lg);
}
}
float avg = cv::sum(cropped)[0] / (cropped.rows * cropped.cols);
cout << avg << endl;
cv::Point2f leftCent(0, 0), rightCent(0, 0);
// iterate left part and right part to find left center point & right center point
int leftCnt = 0, rightCnt = 0;
for (int i = 0; i < cropped.rows; ++i) {
for (int j = 0; j < cropped.cols / 2; ++j) {
if ((float)cropped.data[i * cropped.step + j] * 0.7 > avg) { // can change 0.7 in range (0, 1]
cropped.data[i * cropped.step + j] = 255;
leftCent += cv::Point2f(j, i);
leftCnt++;
}
}
for (int j = cropped.cols / 2; j < cropped.cols; ++j) {
if ((float)cropped.data[i * cropped.step + j] * 0.7 > avg) {
cropped.data[i * cropped.step + j] = 255;
rightCent += cv::Point2f(j, i);
rightCnt++;
}
}
}
cv::waitKey(1);
imshow(filename, frame);
// center point is middle of left center and right center
cv::Point2f centPoint(0, 0);
if (leftCnt != 0)
leftCent.x /= leftCnt; leftCent.y /= leftCnt;
if (rightCnt!= 0)
rightCent.x /= rightCnt; rightCent.y /= rightCnt;
frame.copyTo(frames[cntFrame]);
centPoint = leftCent + rightCent;
if (centPoint.x != 0) centPoint.x /= 2;
if (centPoint.y != 0) centPoint.y /= 2;
centPoints[cntFrame].x = (int)centPoint.x + margin;
centPoints[cntFrame].y = (int)centPoint.y + frame.rows / 4 * 3;
cout << centPoints[cntFrame].x << " " << centPoints[cntFrame].y << endl;
cntFrame++;
}
cout << "Compute cent points: done!" << endl;
displayVideo(frames, centPoints, cntFrame, 15, filename);
delete[] frames;
delete[] centPoints;
cap.release();
cv::destroyAllWindows();
}
int main() {
string video1 = "..\\..\\Data\\01 - Nen tham, duong thang.avi";
string video2 = "..\\..\\Data\\02 - Nen tham, duong cong.avi";
string video3 = "..\\..\\Data\\03 - Nen da hoa, duong thang, vach ngan.avi";
string video4 = "..\\..\\Data\\04 - Nen go, duong cong, nhieu.avi";
string video5 = "..\\..\\Data\\05 - Nen go, nhieu lan duong (multilane).avi";
string videos[5] = {video1, video2, video3, video4, video5};
int margins[5] = {89, 96, 90, 96, 87};
int video = 4;
openVideoFromFile(videos[video - 1], margins[video - 1]);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment