Skip to content

Instantly share code, notes, and snippets.

@ajangrahmat
Created September 3, 2025 15:31
Show Gist options
  • Save ajangrahmat/46a03e3b242dd17c224fd2e5f5ef3642 to your computer and use it in GitHub Desktop.
Save ajangrahmat/46a03e3b242dd17c224fd2e5f5ef3642 to your computer and use it in GitHub Desktop.
import cv2
import numpy as np
# Baca gambar
img = cv2.imread("IMG_20240606_110508.jpg")
# Periksa apakah gambar berhasil dibaca
if img is None:
print("Error: Tidak dapat membaca gambar. Periksa path file.")
exit()
# 1. Convert ke grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 2. Definisikan warna duotone
# Brave Pink #F784C5 -> BGR format
brave_pink_bgr = [0xC5, 0x84, 0xF7] # BGR (OpenCV format)
# Hero Green #1B602F -> BGR format
hero_green_bgr = [0x2F, 0x60, 0x1B] # BGR (OpenCV format)
print(f"Brave Pink BGR: {brave_pink_bgr}")
print(f"Hero Green BGR: {hero_green_bgr}")
# Konversi ke float untuk perhitungan
shadow_color = np.array(hero_green_bgr, dtype=np.float32) # Hijau untuk shadows
highlight_color = np.array(brave_pink_bgr, dtype=np.float32) # Pink untuk highlights
def apply_duotone_precise(gray, shadow_color, highlight_color, gamma=1.0, contrast_boost=0.3):
"""Terapkan duotone dengan kontrol gamma dan contrast yang lebih baik"""
# Normalize ke 0-1
gray_norm = gray.astype(np.float32) / 255.0
# Apply gamma correction
gray_gamma = np.power(gray_norm, gamma)
# Boost contrast dengan stretching histogram
gray_min = np.percentile(gray_gamma, 5)
gray_max = np.percentile(gray_gamma, 95)
gray_stretched = np.clip((gray_gamma - gray_min) / (gray_max - gray_min), 0, 1)
# Apply contrast boost
gray_contrasted = np.clip(gray_stretched * (1 + contrast_boost), 0, 1)
# Buat output duotone
output = np.zeros((gray.shape[0], gray.shape[1], 3), dtype=np.float32)
for i in range(3):
output[:,:,i] = shadow_color[i] * (1 - gray_contrasted) + highlight_color[i] * gray_contrasted
return np.clip(output, 0, 255).astype(np.uint8)
# Coba beberapa variasi gamma untuk mendapatkan hasil terbaik
gamma_values = [0.7, 1.0, 1.3, 1.8]
results = []
for gamma in gamma_values:
result = apply_duotone_precise(gray, shadow_color, highlight_color, gamma=gamma, contrast_boost=0.4)
results.append(result)
filename = f"duotone_gamma_{gamma}.png"
cv2.imwrite(filename, result)
print(f"Disimpan: {filename}")
# Versi dengan preprocessing untuk menggelapkan gambar dulu
def preprocess_darken(img, darkness_factor=0.8):
"""Gelapkan gambar sebelum apply duotone"""
return cv2.convertScaleAbs(img, alpha=darkness_factor, beta=0)
# Versi dengan preprocessing untuk meningkatkan contrast
def preprocess_contrast(img, alpha=1.3, beta=0):
"""Tingkatkan contrast sebelum apply duotone"""
return cv2.convertScaleAbs(img, alpha=alpha, beta=beta)
# Preprocessing: gelapkan dulu kemudian apply duotone
img_darkened = preprocess_darken(img, darkness_factor=0.7)
gray_darkened = cv2.cvtColor(img_darkened, cv2.COLOR_BGR2GRAY)
result_darkened = apply_duotone_precise(gray_darkened, shadow_color, highlight_color, gamma=1.2, contrast_boost=0.5)
# Preprocessing: tingkatkan contrast dulu kemudian apply duotone
img_contrasted = preprocess_contrast(img, alpha=1.4, beta=-20)
gray_contrasted = cv2.cvtColor(img_contrasted, cv2.COLOR_BGR2GRAY)
result_contrasted = apply_duotone_precise(gray_contrasted, shadow_color, highlight_color, gamma=0.9, contrast_boost=0.3)
# Simpan hasil preprocessing
cv2.imwrite("duotone_darkened_first.png", result_darkened)
cv2.imwrite("duotone_contrasted_first.png", result_contrasted)
print("\nHasil tersimpan:")
for gamma in gamma_values:
print(f"- duotone_gamma_{gamma}.png")
print("- duotone_darkened_first.png")
print("- duotone_contrasted_first.png")
# Tampilkan hasil
cv2.imshow("Original", img)
cv2.imshow("Grayscale", gray)
cv2.imshow("Duotone Gamma 0.7 (Darker)", results[0])
cv2.imshow("Duotone Gamma 1.0 (Normal)", results[1])
cv2.imshow("Duotone Gamma 1.3 (Brighter)", results[2])
cv2.imshow("Duotone Darkened First", result_darkened)
cv2.imshow("Duotone Contrasted First", result_contrasted)
print("\nTekan tombol apapun untuk keluar...")
cv2.waitKey(0)
cv2.destroyAllWindows()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment