A Python project for automatic Negative Film inversion
Project description
neginver
Read this in other languages: 中文.
A Python project for automatic Negative Film inversion (color negative film and B+W film).
The trend of film photography has been popular for many days. Now some people have started trying to photograph films themselves. However, for most artists, removing the color cast becomes a "problem" or a "trouble." Although Negative Lab Pro is indeed convenient, its price of $99.00 is prohibitive for poor people like me, and I am not too fond of its overly flattering color correction approach. Therefore, I developed this simple negative film color cast removal program, hoping to help everyone!
The project can inverse pictures from this ⬇️ To this ⬇️ E-mail: flemyng1999@outlook.com
Installation
You can install it using pip:
pip install neginver
I'm quite lazy, so there's no conda version yet.
Usage
This project currently does not have a GUI, so it still requires users to have some Python basics.
Read Tif files. This step reads the Tif files as numpy arrays based on tifffile:
import tifffile as tiff
img = tiff.imread(tif_path)
Since I am accustomed to the [band, height, width] format, and tiff.imread() reads it as [height, width, band] format, a simple numpy operation is required:
import numpy as np
img = np.moveaxis(img, 0, -1)
Then import this module:
import neginver as ni
img_inversed = ni.negative_inverse(img_raw, film_type='color', mode='default')
Then save the img_inversed array as a lossless Tif file:
img_final = np.moveaxis(img_inversed, 0, -1)
tiff.imwrite('img.tif', img_final)
This is the process for one image. You can use loops for batch processing. Based on tests on my M2 Pro MacBook Pro, processing a 12-megapixel image takes only 2.5 seconds:
import os
from pathlib import Path
from datetime import datetime
import tifffile as tiff
import numpy as np
import neginver as ni
# Directory path
data_dir = Path('/Users/flemyng/Desktop/Phocus/2024_05_24')
save_dir = Path('/Users/flemyng/Desktop/Film')
# Get all *.tif files in the directory
tif_files = list(data_dir.glob('*.tif'))
# Resort the list of files
tif_files = sorted(tif_files)
# Get now time
current_date = datetime.now()
# Change date to YYYY_MM_DD
folder_name = current_date.strftime('%Y_%m_%d')
# Initialize a new folder
os.makedirs(save_dir / folder_name, exist_ok=True)
for tif_path in tqdm(tif_files):
img_raw = np.moveaxis(tiff.imread(tif_path), -1, 0)
img_inversed = ni.negative_inverse(img_raw, film_type='color', mode='default')
img = np.moveaxis(img_inversed, 0, -1)
tiff.imwrite(
save_dir / folder_name / f'{tif_path.stem}.tif',
img
)
Finally, I recommend making some simple edits to the Tone Curve in Lightroom according to your own aesthetic preferences.
negative_inverse()
The negative_inverse() function is the core function of this module. The parameters of the negative_inverse() function and how to use them are as follows:
Input Parameters
img: np.ndarray,
film_type: str, # 'color', 'bw'
mode: str,
rates: tuple[float],
percentile: float,
crop_percentage: float,
Parameter Descriptions
img: A numpy array of shape [3, height, width] containing the original image information. The array dtype only supports uint8 and uint16, and uint16 is more than enough. Float is not supported because negatives are quite troublesome;
film_type: The type of film. If it's color film, choose 'color'; for black and white film, choose 'bw'. 'Color' can also be used for black and white film;
mode: The color correction mode. There are three choices: 'auto', 'default', 'manual'. The default is 'default'; 'auto' generally tends to green and blue, so you need to adjust the curve yourself a bit (simply lower the center a bit); 'manual' is not recommended, this is what I use myself.
crop_percentage: The proportion of the black border around the film (from 0 to 1). For example, 0.05 means ignoring information in the outermost 5% range of the image.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.