Skip to content

Commit

Permalink
Merge branch 'release/v1.0.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
rsnitsch committed Aug 29, 2023
2 parents a0dea28 + 3c69c1c commit f761178
Show file tree
Hide file tree
Showing 12 changed files with 337 additions and 117 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ _install/
**.avi
**.mp4
**.png
**.jpg
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
*.mp4
_build/
_install/
*/CACHEDIR.TAG
6 changes: 5 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
"files.associations": {
"iostream": "cpp",
"vector": "cpp",
"xstring": "cpp"
"xstring": "cpp",
"array": "cpp",
"istream": "cpp",
"tuple": "cpp",
"utility": "cpp"
},
"editor.formatOnSave": true
}
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
# Changelog

## v1.0.2

*Release date: 2023/08/29*

* Only attempt to detect line starts/ends in rows with pure black at the edge. (commit 1199036)
* Fix rare bugs in the line-start gap extrapolation logic (commits e80e373 and b9c1527)
* Improve error messages, make them more informative and user-friendly
* Make parsing of framerate parameter more strict and print the framerate that is being used (and
where it is taken from, i.e. from commandline parameter or input file).
* Fix calculation of line-start values for other `colRange` values (commmit 0bd2627)
* Not relevant for users yet, but an important preparation for the commandline options
that are planned for allowing to change parameters like `colRange`
* refactor line gap interpolation. Interpolation and extrapolation are now performed by
two separate functions, resulting in much cleaner code (commit bdb7e95).
* The **Docker image** is now based on Debian 12 (bookworm) and uses OpenCV 4.6.0. Previously
Debian 11 (bullseye) was used with OpenCV 4.5.3.

## v1.0.1

*Release date: 2023/04/09*
Expand Down
12 changes: 6 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM debian:stable AS builder
FROM debian:12 AS builder
LABEL org.opencontainers.image.authors="[email protected]"
LABEL org.opencontainers.image.version="1.0.1"
LABEL org.opencontainers.image.version="1.0.2"
LABEL org.opencontainers.image.title="Fix horizontal shaking in digitized VHS videos"
LABEL org.opencontainers.image.url="https://github.com/rsnitsch/vhs-deshaker"

Expand All @@ -22,10 +22,10 @@ RUN cmake --install _build/
# -----------------------------------

FROM debian:stable
RUN apt-get update && apt-get -y upgrade && apt-get install -y libopencv-core4.5 \
libopencv-highgui4.5 \
libopencv-imgproc4.5 \
libopencv-videoio4.5 \
RUN apt-get update && apt-get -y upgrade && apt-get install -y libopencv-core406 \
libopencv-highgui406 \
libopencv-imgproc406 \
libopencv-videoio406 \
&& rm -rf /var/lib/apt/lists/*
COPY --from=builder /vhs-deshaker/_install/bin/vhs-deshaker /usr/bin/vhs-deshaker
WORKDIR /videos
Expand Down
31 changes: 29 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
# vhs-deshaker
# vhs-deshaker <!-- omit from toc -->

This tool is for fixing a very specific horizontal shaking issue that affects some digitized VHS videos.

## Table of Contents <!-- omit from toc -->

- [Example](#example)
- [How does vhs-deshaker work?](#how-does-vhs-deshaker-work)
- [Install](#install)
- [Usage](#usage)
- [Build instructions](#build-instructions)
- [Docker image](#docker-image)
- [Docker troubleshooting: Input file cannot be opened](#docker-troubleshooting-input-file-cannot-be-opened)
- [See also](#see-also)

## Example

Input example:

https://user-images.githubusercontent.com/1746428/225921679-25f9ba88-bee2-4557-9181-5fd0df6a07b4.mp4
Expand Down Expand Up @@ -81,15 +94,29 @@ See BUILD.md.

## Docker image

You can also run vhs-deshaker via docker. I provide a docker image at ``rsnitsch/vhs-deshaker:latest``.
You can also run vhs-deshaker via docker. I provide a docker image at [`rsnitsch/vhs-deshaker`](https://hub.docker.com/r/rsnitsch/vhs-deshaker).

Example command:

docker run -it --rm -v "$(pwd):/videos" --user $(id -u):$(id -g) rsnitsch/vhs-deshaker:latest <input-file> <output-file> [<framerate>]

### Docker troubleshooting: Input file cannot be opened

If the input file cannot be opened, double-check that your input file is actually visible within docker. The option `-v "$(pwd):/videos"`
*should* map the current working directory (on your host system) inside the docker container at `/videos` (which is the working directory
of vhs-deshaker inside the docker container).

You can use the following command to list the files visible inside the vhs-deshaker docker container at `/videos`:

docker run --entrypoint ls -it --rm -v "$(pwd):/videos" --user $(id -u):$(id -g) rsnitsch/vhs-deshaker:latest -Al

This executes `ls -Al` inside the docker container which lists the files in `/videos`. You should see the same contents as in your
current working directory on your host system. If not, then you have to find out why and fix this first.

## See also

Online threads discussing the issue:

- https://forum.videohelp.com/threads/394670-VHS-Horizontal-Stabilisation
- https://forum.videohelp.com/threads/392186-Way-too-shakey-captured-VHS-video
- https://forum.doom9.org/showthread.php?t=174756
20 changes: 20 additions & 0 deletions TODOs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# TODOs

## Features

- add `--col-range` commandline option
- add `--framerate` commandline option (replacing the previously used *positional* framerate parameter)
- add commandline parameter to set `TARGET_LINE_START`. This is the regular/ideal width of the pure black
area at the left and right sides of the video frames. So it could get a new name like `PURE_BLACK_WIDTH`
and get a corresponding commandline option `--pure-black-width`.
- add `--min-segment-length` commandline option (parameter for `denoise_line_starts`)
- `draw_line_starts` should use a better visualization for negative line_starts. Idea: For a row with negative line_start value, fill up the pixels from the *opposite* side with a bright (e.g. red) color that
indicates the area where information is lost. Actually this idea should be expanded to all **extreme** line_start values. (big positive line_starts are also leading to data loss.)

## Refactoring / Code cleanup

- `line_ends` do not actually refer to end positions, instead they're just line_starts
determined by scanning from the end (right side) of the rows. this distinction should be made clearer
because I bet it will utterly confuse some people.
- `draw_line_starts` adds to the confusion because you can pass `line_ends` with an `x_offset` to draw
the edge at the right side of the image frame
9 changes: 5 additions & 4 deletions include/correct_frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,16 @@
* enough to find the majority of line starts in the frame. For example, for mild cases of shaking/distortion a value of
* 2 * PURE_BLACK_START_COLUMN is sufficient, where PURE_BLACK_START_COLUMN is the column
* where the pure black starts in your digitized VHS video.
* @param grayBuffer A Mat that can be reused as buffer for the grayscale version of the input frame.
* @param grayBuffer1 A Mat that can be reused as buffer for the grayscale version of the input frame (left border).
* @param grayBuffer1 A Mat that can be reused as buffer for the grayscale version of the input frame (right border).
* @param sobelBuffer1 A Mat that can be reused as buffer for the first Sobel-processed frame region (at left border).
* @param sobelBuffer2 A Mat that can be reused as buffer for the second Sobel-processed frame regions (at right border).
* @param sobelBuffer2 A Mat that can be reused as buffer for the second Sobel-processed frame region (at right border).
* @param line_starts_buffer A vector that can be reused as buffer to store line starts.
* @param line_ends_buffer A vector that can be reused as buffer to store line ends.
* @param out The corrected output frame (BGR).
*/
void correct_frame(cv::Mat &input, const int colRange, cv::Mat &grayBuffer, cv::Mat &sobelBuffer1, cv::Mat &sobelBuffer2,
std::vector<int> &line_starts_buffer, std::vector<int> &line_ends_buffer, cv::Mat &out);
void correct_frame(cv::Mat &input, const int colRange, cv::Mat &grayBuffer1, cv::Mat &grayBuffer2, cv::Mat &sobelBuffer1,
cv::Mat &sobelBuffer2, std::vector<int> &line_starts_buffer, std::vector<int> &line_ends_buffer, cv::Mat &out);

/**
* Draw line starts into an image frame for debugging purposes.
Expand Down
3 changes: 3 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ if(WIN32)
get_target_property(opencv_world_dll_source_filepath opencv_world IMPORTED_LOCATION_RELEASE)
install(FILES ${opencv_world_dll_source_filepath} DESTINATION bin)

get_target_property(opencv_world_dll_source_filepath opencv_world IMPORTED_LOCATION_DEBUG)
install(FILES ${opencv_world_dll_source_filepath} DESTINATION bin)

file(GLOB opencv_ffmpeg_dll "${OpenCV_DIR}/x64/vc16/bin/opencv_videoio_ffmpeg*.dll")
install(FILES ${opencv_ffmpeg_dll} DESTINATION bin)
endif()
Loading

0 comments on commit f761178

Please sign in to comment.