Initialize project

This commit is contained in:
Matt McWilliams 2025-12-16 15:31:33 -08:00
commit 9113e2edea
19 changed files with 27609 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
build
notes/env

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "include/args"]
path = include/args
url = https://github.com/Taywee/args.git

35
CMakeLists.txt Normal file
View File

@ -0,0 +1,35 @@
cmake_minimum_required(VERSION 3.9)
project(filmout_image)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules)
set(TESTING_ON FALSE)
find_package(OpenCV HINTS /usr/local/opt/opencv /usr/local/Cellar/opencv REQUIRED)
file(GLOB SOURCES "src/*.cpp")
if(${TESTING_ON})
ENABLE_TESTING()
ADD_SUBDIRECTORY( test )
SET(UNIT_TEST state_test)
add_test(NAME ${UNIT_TEST} COMMAND ${UNIT_TEST})
add_custom_target(run_unit_test ALL
COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure
DEPENDS ${UNIT_TEST})
endif()
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
add_executable( fi ${SOURCES} )
target_include_directories(fi PRIVATE include)
if (APPLE)
target_link_libraries(fi ${OpenCV_LIBS} pthread)
else()
target_link_libraries(fi ${OpenCV_LIBS} pthread)
endif()

19
LICENSE Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2025 Matthew McWilliams
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

5
README.md Normal file
View File

@ -0,0 +1,5 @@
# filmout_image
Provides the image manipulation and channel separation features for the filmout program.
Decouples the behavior from filmout_display to allow that program to remained optimized and keep these operations in their own application.

View File

@ -0,0 +1,173 @@
# ===================================================================================
# The OpenCV CMake configuration file
#
# ** File generated automatically, do not modify **
#
# Usage from an external project:
# In your CMakeLists.txt, add these lines:
#
# FIND_PACKAGE(OpenCV REQUIRED)
# TARGET_LINK_LIBRARIES(MY_TARGET_NAME ${OpenCV_LIBS})
#
# Or you can search for specific OpenCV modules:
#
# FIND_PACKAGE(OpenCV REQUIRED core imgcodecs)
#
# If the module is found then OPENCV_<MODULE>_FOUND is set to TRUE.
#
# This file will define the following variables:
# - OpenCV_LIBS : The list of libraries to link against.
# - OpenCV_LIB_DIR : The directory(es) where lib files are. Calling LINK_DIRECTORIES
# with this path is NOT needed.
# - OpenCV_INCLUDE_DIRS : The OpenCV include directories.
# - OpenCV_COMPUTE_CAPABILITIES : The version of compute capability
# - OpenCV_ANDROID_NATIVE_API_LEVEL : Minimum required level of Android API
# - OpenCV_VERSION : The version of this OpenCV build. Example: "2.4.0"
# - OpenCV_VERSION_MAJOR : Major version part of OpenCV_VERSION. Example: "2"
# - OpenCV_VERSION_MINOR : Minor version part of OpenCV_VERSION. Example: "4"
# - OpenCV_VERSION_PATCH : Patch version part of OpenCV_VERSION. Example: "0"
#
# Advanced variables:
# - OpenCV_SHARED
# - OpenCV_CONFIG_PATH
# - OpenCV_LIB_COMPONENTS
#
# ===================================================================================
#
# Windows pack specific options:
# - OpenCV_STATIC
# - OpenCV_CUDA
if(CMAKE_VERSION VERSION_GREATER 2.6)
get_property(OpenCV_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
if(NOT ";${OpenCV_LANGUAGES};" MATCHES ";CXX;")
enable_language(CXX)
endif()
endif()
if(NOT DEFINED OpenCV_STATIC)
# look for global setting
if(BUILD_SHARED_LIBS)
set(OpenCV_STATIC OFF)
else()
set(OpenCV_STATIC ON)
endif()
endif()
if(NOT DEFINED OpenCV_CUDA)
# if user' app uses CUDA, then it probably wants CUDA-enabled OpenCV binaries
if(CUDA_FOUND)
set(OpenCV_CUDA ON)
endif()
endif()
if(MSVC)
if(CMAKE_CL_64)
set(OpenCV_ARCH x64)
set(OpenCV_TBB_ARCH intel64)
elseif((CMAKE_GENERATOR MATCHES "ARM") OR ("${arch_hint}" STREQUAL "ARM") OR (CMAKE_VS_EFFECTIVE_PLATFORMS MATCHES "ARM|arm"))
# see Modules/CmakeGenericSystem.cmake
set(OpenCV_ARCH ARM)
else()
set(OpenCV_ARCH x86)
set(OpenCV_TBB_ARCH ia32)
endif()
if(MSVC_VERSION EQUAL 1400)
set(OpenCV_RUNTIME vc8)
elseif(MSVC_VERSION EQUAL 1500)
set(OpenCV_RUNTIME vc9)
elseif(MSVC_VERSION EQUAL 1600)
set(OpenCV_RUNTIME vc10)
elseif(MSVC_VERSION EQUAL 1700)
set(OpenCV_RUNTIME vc11)
elseif(MSVC_VERSION EQUAL 1800)
set(OpenCV_RUNTIME vc12)
elseif(MSVC_VERSION EQUAL 1900)
set(OpenCV_RUNTIME vc14)
endif()
elseif(MINGW)
set(OpenCV_RUNTIME mingw)
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpmachine
OUTPUT_VARIABLE OPENCV_GCC_TARGET_MACHINE
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(OPENCV_GCC_TARGET_MACHINE MATCHES "amd64|x86_64|AMD64")
set(MINGW64 1)
set(OpenCV_ARCH x64)
else()
set(OpenCV_ARCH x86)
endif()
endif()
if(CMAKE_VERSION VERSION_GREATER 2.6.2)
unset(OpenCV_CONFIG_PATH CACHE)
endif()
if(NOT OpenCV_FIND_QUIETLY)
message(STATUS "OpenCV ARCH: ${OpenCV_ARCH}")
message(STATUS "OpenCV RUNTIME: ${OpenCV_RUNTIME}")
message(STATUS "OpenCV STATIC: ${OpenCV_STATIC}")
endif()
get_filename_component(OpenCV_CONFIG_PATH "${CMAKE_CURRENT_LIST_FILE}" PATH CACHE)
if(OpenCV_RUNTIME AND OpenCV_ARCH)
if(OpenCV_STATIC AND EXISTS "${OpenCV_CONFIG_PATH}/${OpenCV_ARCH}/${OpenCV_RUNTIME}/staticlib/OpenCVConfig.cmake")
if(OpenCV_CUDA AND EXISTS "${OpenCV_CONFIG_PATH}/gpu/${OpenCV_ARCH}/${OpenCV_RUNTIME}/staticlib/OpenCVConfig.cmake")
set(OpenCV_LIB_PATH "${OpenCV_CONFIG_PATH}/gpu/${OpenCV_ARCH}/${OpenCV_RUNTIME}/staticlib")
else()
set(OpenCV_LIB_PATH "${OpenCV_CONFIG_PATH}/${OpenCV_ARCH}/${OpenCV_RUNTIME}/staticlib")
endif()
elseif(EXISTS "${OpenCV_CONFIG_PATH}/${OpenCV_ARCH}/${OpenCV_RUNTIME}/lib/OpenCVConfig.cmake")
if(OpenCV_CUDA AND EXISTS "${OpenCV_CONFIG_PATH}/gpu/${OpenCV_ARCH}/${OpenCV_RUNTIME}/lib/OpenCVConfig.cmake")
set(OpenCV_LIB_PATH "${OpenCV_CONFIG_PATH}/gpu/${OpenCV_ARCH}/${OpenCV_RUNTIME}/lib")
else()
set(OpenCV_LIB_PATH "${OpenCV_CONFIG_PATH}/${OpenCV_ARCH}/${OpenCV_RUNTIME}/lib")
endif()
endif()
endif()
if(OpenCV_LIB_PATH AND EXISTS "${OpenCV_LIB_PATH}/OpenCVConfig.cmake")
set(OpenCV_LIB_DIR_OPT "${OpenCV_LIB_PATH}" CACHE PATH "Path where release OpenCV libraries are located" FORCE)
set(OpenCV_LIB_DIR_DBG "${OpenCV_LIB_PATH}" CACHE PATH "Path where debug OpenCV libraries are located" FORCE)
set(OpenCV_3RDPARTY_LIB_DIR_OPT "${OpenCV_LIB_PATH}" CACHE PATH "Path where release 3rdparty OpenCV dependencies are located" FORCE)
set(OpenCV_3RDPARTY_LIB_DIR_DBG "${OpenCV_LIB_PATH}" CACHE PATH "Path where debug 3rdparty OpenCV dependencies are located" FORCE)
include("${OpenCV_LIB_PATH}/OpenCVConfig.cmake")
if(OpenCV_CUDA)
set(_OpenCV_LIBS "")
foreach(_lib ${OpenCV_LIBS})
string(REPLACE "${OpenCV_CONFIG_PATH}/gpu/${OpenCV_ARCH}/${OpenCV_RUNTIME}" "${OpenCV_CONFIG_PATH}/${OpenCV_ARCH}/${OpenCV_RUNTIME}" _lib2 "${_lib}")
if(NOT EXISTS "${_lib}" AND EXISTS "${_lib2}")
list(APPEND _OpenCV_LIBS "${_lib2}")
else()
list(APPEND _OpenCV_LIBS "${_lib}")
endif()
endforeach()
set(OpenCV_LIBS ${_OpenCV_LIBS})
endif()
set(OpenCV_FOUND TRUE CACHE BOOL "" FORCE)
set(OPENCV_FOUND TRUE CACHE BOOL "" FORCE)
if(NOT OpenCV_FIND_QUIETLY)
message(STATUS "Found OpenCV ${OpenCV_VERSION} in ${OpenCV_LIB_PATH}")
if(NOT OpenCV_LIB_PATH MATCHES "/staticlib")
get_filename_component(_OpenCV_LIB_PATH "${OpenCV_LIB_PATH}/../bin" ABSOLUTE)
file(TO_NATIVE_PATH "${_OpenCV_LIB_PATH}" _OpenCV_LIB_PATH)
message(STATUS "You might need to add ${_OpenCV_LIB_PATH} to your PATH to be able to run your applications.")
if(OpenCV_LIB_PATH MATCHES "/gpu/")
string(REPLACE "\\gpu" "" _OpenCV_LIB_PATH2 "${_OpenCV_LIB_PATH}")
message(STATUS "GPU support is enabled so you might also need ${_OpenCV_LIB_PATH2} in your PATH (it must go after the ${_OpenCV_LIB_PATH}).")
endif()
endif()
endif()
else()
if(NOT OpenCV_FIND_QUIETLY)
message(WARNING
"Found OpenCV Windows Pack but it has no binaries compatible with your configuration.
You should manually point CMake variable OpenCV_DIR to your build of OpenCV library."
)
endif()
set(OpenCV_FOUND FALSE CACHE BOOL "" FORCE)
set(OPENCV_FOUND FALSE CACHE BOOL "" FORCE)
endif()

8
compile.sh Normal file
View File

@ -0,0 +1,8 @@
#!/bin/bash
rm -rf build
mkdir -p build
cd build
cmake ..
make -j4

27153
error.txt Normal file

File diff suppressed because it is too large Load Diff

36
include/FilmoutImage.hpp Normal file
View File

@ -0,0 +1,36 @@
#ifndef FILMOUT_IMAGE_h
#define FILMOUT_IMAGE_h
#include <opencv2/core.hpp>
#include <opencv2/core/opengl.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <cstdint>
using namespace std;
using namespace cv;
class FilmoutImage {
private:
vector<Mat> channels;
vector<Mat> sub_channels;
Mat loaded;
Mat combined;
Mat empty;
Mat red;
Mat green;
Mat blue;
Mat combineChannel(Mat data, Mat empty, uint8_t i);
public:
void loadChannels(string image_path, uint64_t x, uint64_t y, uint64_t w, uint64_t h);
Mat getRed();
Mat getGreen();
Mat getBlue();
};
#endif

1
include/args Submodule

@ -0,0 +1 @@
Subproject commit 114200a9ad5fe06c8dea76e15d92325695cf3e34

21
notes/bwprint.py Normal file
View File

@ -0,0 +1,21 @@
import cv2
import numpy as np
img = cv2.imread('grayscale1.png')
# convert color method
bw = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
bwneg = cv2.bitwise_not(bw)
# LAB brightness extraction?
alpha = 0.8 #test with grayscale on 3302
beta = 0
bwneg_adjusted = cv2.convertScaleAbs(bwneg, alpha=alpha, beta=beta)
cv2.imshow('BW Negative Channel', bwneg_adjusted)
cv2.waitKey(0)
cv2.destroyAllWindows()

18
notes/cmy.py Normal file
View File

@ -0,0 +1,18 @@
import cv2
import numpy as np
img = cv2.imread('color_checker.png')
black = np.zeros(img.shape[:2], dtype='uint8')
(B, G, R) = cv2.split(img)
cyan = cv2.merge([B, G, black])
magenta = cv2.merge([B, black, R])
yellow = cv2.merge([black, G, R])
cv2.imshow('Cyan Channel', cyan)
cv2.imshow('Magenta Channel', magenta)
cv2.imshow('Yellow Channel', yellow)
cv2.waitKey(0)
cv2.destroyAllWindows()

BIN
notes/color_checker.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
notes/grayscale1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

1
notes/requirements.txt Normal file
View File

@ -0,0 +1 @@
opencv-python

20
notes/rgb.py Normal file
View File

@ -0,0 +1,20 @@
import cv2
import numpy as np
img = cv2.imread('color_checker.png')
black = np.zeros(img.shape[:2], dtype='uint8')
(B, G, R) = cv2.split(img)
blue = cv2.merge([B, black, black])
green = cv2.merge([black, G, black])
red = cv2.merge([black, black, R])
cv2.imshow('Red Channel', red)
cv2.imshow('Green Channel', green)
cv2.imshow('Blue Channel', blue)
cv2.waitKey(0)
cv2.destroyAllWindows()

BIN
notes/srgb_circle.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

80
src/FilmoutImage.cpp Normal file
View File

@ -0,0 +1,80 @@
#include "FilmoutImage.cpp"
void FilmoutImage::loadChannels (string image_path, uint64_t x, uint64_t y, uint64_t w, uint64_t h) {
string located_path = samples::findFile(image_path);
string ext = getExtLower(located_path);
if (ext == "dpx") {
//NOT WORKING
cout << "{ \"dpx\" : \"" << image_path << "\" }" << endl;
} else {
loaded = imread(located_path, IMREAD_COLOR);
}
if (loaded.empty()) {
cerr << "{ \"error\" : \"" << image_path << " empty\" }" << endl;
} else {
resize(loaded, resized, Size(w, h));
empty = Mat::zeros(Size(width, height), CV_8UC1);
split(resized, channels);
combined = combineChannel(blue, empty, 0);
combined.copyTo(red(Rect(x, y, resized.cols, resized.rows)));
flip(red, red, 0);
combined = combineChannel(green, empty, 1);
combined.copyTo(green(Rect(x, y, resized.cols, resized.rows)));
flip(green, green, 0);
combined = combineChannel(red, empty, 2);
combined.copyTo(red(Rect(x, y, resized.cols, resized.rows)));
flip(red, red, 0);
#if (CV_VERSION_MAJOR >= 4)
cvtColor(red, red, cv::COLOR_BGR2RGB);
cvtColor(green, green, cv::COLOR_BGR2RGB);
cvtColor(blue, blue, cv::COLOR_BGR2RGB);
#else
cvtColor(red, red, CV_BGR2RGB);
cvtColor(green, green, CV_BGR2RGB);
cvtColor(blue, blue, CV_BGR2RGB);
#endif
loaded.release();
resized.release();
empty.release();
combined.release();
for (uint8_t i = 0; i < 3; i++) {
channels[i].release();
sub_channels[i].release();
}
//UPDATE TO RGB channel loading message
cout << "{ \"loaded\" : \"" << image_path << "\", ";
cout << "\"original\" : { \"w\" : " << loaded.cols << ", \"h\" : " << loaded.rows << " }, ";
cout << "\"resized\" : { \"w\" : " << resized.cols << ", \"h\" : " << resized.rows << " } }" << endl;
}
}
Mat FilmoutImage::combineChannel(Mat data, Mat empty, uint8_t i) {
//BGR
sub_channels[0] = i == 0 ? data : empty;
sub_channels[1] = i == 1 ? data : empty;
sub_channels[2] = i == 2 ? data : empty;
merge(sub_channels, combined);
return combined;
}
Mat FilmoutImage::getRed () {
return red;
}
Mat FilmoutImage::getGreen () {
return green;
}
Mat FilmoutImage::getBlue () {
return blue;
}

34
src/main.cpp Normal file
View File

@ -0,0 +1,34 @@
#include "FilmoutImage.hpp"
#include "args/args.hxx"
using namespace std;
int main (int argc, char** argv) {
args::ArgumentParser parser("filmout_image", "Manipulates images for filmout");
args::HelpFlag help(parser, "help", "Display this help menu", {'h', "help"});;
try
{
parser.ParseCLI(argc, argv);
}
catch (args::Help)
{
std::cout << parser;
return 0;
}
catch (args::ParseError e)
{
std::cerr << e.what() << std::endl;
std::cerr << parser;
return 1;
}
catch (args::ValidationError e)
{
std::cerr << e.what() << std::endl;
std::cerr << parser;
return 1;
}
return 0;
}