Add center_video.cpp
This commit is contained in:
parent
4a011689ab
commit
2301af6e2d
177
src/center_video.cpp
Normal file
177
src/center_video.cpp
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
|
||||||
|
#define WIDTH 1920
|
||||||
|
#define HEIGHT 1080
|
||||||
|
#define ACCEPTED_BLANK 20
|
||||||
|
#define ACCEPTED_NON_BG 10
|
||||||
|
#define SHOW_PROGRESS
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
cv::Scalar backgroundColor(255, 255, 255);
|
||||||
|
cv::Scalar blue(249, 0, 0);
|
||||||
|
|
||||||
|
|
||||||
|
bool is_background (const cv::Vec3b& pixel) {
|
||||||
|
// Upper bound: 195075
|
||||||
|
return abs((pixel[0] - backgroundColor[0])*(pixel[1] - backgroundColor[1])*(pixel[2] - backgroundColor[2])) < 5000;
|
||||||
|
};
|
||||||
|
|
||||||
|
cv::Rect get_pos(const cv::Mat& frame) {
|
||||||
|
bool no_break = true;
|
||||||
|
int left_margin = -1;
|
||||||
|
int right_margin = -1;
|
||||||
|
|
||||||
|
for (int i=0; i < frame.cols; i++) {
|
||||||
|
bool contains_non_white = false;
|
||||||
|
for (int j=0; j < frame.rows; j++) {
|
||||||
|
int non_bg = 0;
|
||||||
|
if (!is_background(frame.at<cv::Vec3b>(j, i))) {
|
||||||
|
contains_non_white = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (no_break && !contains_non_white) {
|
||||||
|
left_margin += 1;
|
||||||
|
} else if (contains_non_white) {
|
||||||
|
no_break = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contains_non_white) {
|
||||||
|
right_margin = i+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
right_margin = min(right_margin, frame.cols-1);
|
||||||
|
|
||||||
|
// Iterate over the lines and find the tallest block of non-white lines, this will give us
|
||||||
|
// the vertical size of the rectangle, i.e the top and bottom margins
|
||||||
|
int top_margin = -1;
|
||||||
|
int bottom_margin = -1;
|
||||||
|
int max_height = 0;
|
||||||
|
|
||||||
|
int cur_height = -1;
|
||||||
|
int cur_top_margin = 0;
|
||||||
|
|
||||||
|
int echecs = 0;
|
||||||
|
|
||||||
|
for (int i=0; i < frame.rows; i++) {
|
||||||
|
bool contains_non_white = false;
|
||||||
|
int non_bg = 0;
|
||||||
|
for (int j=0; j < frame.cols; j++) {
|
||||||
|
if (!is_background(frame.at<cv::Vec3b>(i, j))) {
|
||||||
|
if (++non_bg >= ACCEPTED_NON_BG) {
|
||||||
|
contains_non_white = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!contains_non_white) {
|
||||||
|
if (++echecs >= ACCEPTED_BLANK) {
|
||||||
|
if (cur_height >= max_height) {
|
||||||
|
max_height = cur_height;
|
||||||
|
top_margin = cur_top_margin;
|
||||||
|
bottom_margin = cur_top_margin + cur_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_height = -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cur_height += 1;
|
||||||
|
if (cur_height == 0) {
|
||||||
|
cur_top_margin = i;
|
||||||
|
}
|
||||||
|
echecs = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cur_height >= max_height) {
|
||||||
|
max_height = cur_height;
|
||||||
|
top_margin = cur_top_margin;
|
||||||
|
bottom_margin = cur_top_margin + cur_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
//cout << "top: " << top_margin << ", bottom: " << bottom_margin << ", height: " << max_height << endl;
|
||||||
|
bottom_margin = min(bottom_margin, frame.rows-1);
|
||||||
|
|
||||||
|
|
||||||
|
cv::Rect rect = cv::Rect(left_margin, top_margin, right_margin-left_margin, bottom_margin-top_margin);
|
||||||
|
// Return a rectangle covering all the frame except the left margin
|
||||||
|
//cv::Rect rect = cv::Rect(left_margin, 0, right_margin-left_margin, frame.rows-1);
|
||||||
|
//cout << rect << endl;
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
if (argc != 3) {
|
||||||
|
cerr << "Usage: " << argv[0] << " <input_video_file> <output_video_file>" << endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open the input video file
|
||||||
|
cv::VideoCapture inputVideo(argv[1]);
|
||||||
|
if (!inputVideo.isOpened()) {
|
||||||
|
cerr << "Error: Could not open input video file." << endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get input video properties
|
||||||
|
int inputWidth = inputVideo.get(cv::CAP_PROP_FRAME_WIDTH);
|
||||||
|
int inputHeight = inputVideo.get(cv::CAP_PROP_FRAME_HEIGHT);
|
||||||
|
int totalFrames = static_cast<int>(inputVideo.get(cv::CAP_PROP_FRAME_COUNT));
|
||||||
|
|
||||||
|
// Create video writer for the output video
|
||||||
|
cv::VideoWriter outputVideo(argv[2], cv::VideoWriter::fourcc('X', '2', '6', '4'), inputVideo.get(cv::CAP_PROP_FPS),
|
||||||
|
cv::Size(WIDTH, HEIGHT), true);
|
||||||
|
|
||||||
|
if (!outputVideo.isOpened()) {
|
||||||
|
cerr << "Error: Could not open output video file for writing." << endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process each frame
|
||||||
|
cv::Mat frame;
|
||||||
|
int currentFrame = 0;
|
||||||
|
int last_progress = -1;
|
||||||
|
while (inputVideo.read(frame)) {
|
||||||
|
// Get the rectangle to keep using the get_pos function
|
||||||
|
cv::Rect roi = get_pos(frame);
|
||||||
|
|
||||||
|
cv::Mat resizedFrame(HEIGHT, WIDTH, frame.type(), blue);
|
||||||
|
frame(roi).copyTo(resizedFrame(cv::Rect((WIDTH - roi.width) / 2, (HEIGHT - roi.height) / 2, roi.width, roi.height)));
|
||||||
|
|
||||||
|
// Write the modified frame to the output video
|
||||||
|
outputVideo.write(resizedFrame);
|
||||||
|
|
||||||
|
// Update and display progress bar
|
||||||
|
currentFrame++;
|
||||||
|
|
||||||
|
#ifdef SHOW_PROGRESS
|
||||||
|
float progress = static_cast<float>(currentFrame) / totalFrames;
|
||||||
|
int barWidth = 50;
|
||||||
|
int pos = static_cast<int>(barWidth * progress);
|
||||||
|
|
||||||
|
int progress_percent = static_cast<int>(progress * 100.0);
|
||||||
|
if (progress_percent != last_progress) {
|
||||||
|
cout << "[";
|
||||||
|
for (int i = 0; i < barWidth; ++i) {
|
||||||
|
if (i < pos) cout << "=";
|
||||||
|
else if (i == pos) cout << ">";
|
||||||
|
else cout << " ";
|
||||||
|
}
|
||||||
|
cout << "] " << int(progress * 100.0) << "% " << roi << "\r";
|
||||||
|
cout.flush();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Release video capture and writer objects
|
||||||
|
inputVideo.release();
|
||||||
|
outputVideo.release();
|
||||||
|
|
||||||
|
cout << "Video processing complete. Output saved to: " << argv[2] << endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user