Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add LUT and processing with OpenCV #28

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,4 @@ venv.bak/

# mypy
.mypy_cache/
/.idea
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.0.2
1.1.3
6 changes: 6 additions & 0 deletions handyview/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ def history(parent):
return new_action(parent, 'History', icon_name='history.png', slot=parent.open_history)


def LUT(parent):
"""Show open LUT."""
return new_action(parent, 'LUT', icon_name='LUT.png', slot=parent.open_LUT)


# ---------------------------------------
# refresh and index
# ---------------------------------------
Expand Down Expand Up @@ -138,6 +143,7 @@ def set_fingerprint(parent):
# ---------------------------------------
# auto zoom
# ---------------------------------------

def auto_zoom(parent):
return new_action(parent, 'Auto Zoom', icon_name='auto_zoom.png', slot=parent.auto_zoom)

Expand Down
75 changes: 68 additions & 7 deletions handyview/canvas.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import os

import numpy as np
from PyQt5 import QtCore
from PyQt5.QtGui import QColor, QImage, QPainter, QPen, QPixmap
from PyQt5.QtGui import QColor, QImage, QPainter, QPen, QPixmap, qRgb
from PyQt5.QtWidgets import QApplication, QGridLayout, QSplitter, QWidget

from handyview.view_scene import HVScene, HVView
from handyview.widgets import ColorLabel, HVLable, show_msg

# For LUT
import cv2

class Canvas(QWidget):
"""Main canvas"""
Expand Down Expand Up @@ -192,7 +195,7 @@ def add_cmp_folder(self, cmp_path):
show_str = 'Number for each folder:\n\t' + '\n\t'.join(map(str, img_len_list))
self.comparison_label.setText(show_str)
if is_same_len is False:
msg = f'Comparison folders have differnet number of images.\n{show_str}'
msg = f'Comparison folders have different number of images.\n{show_str}'
show_msg('Warning', 'Warning!', msg)
# refresh
self.show_image()
Expand All @@ -202,7 +205,7 @@ def update_path_list(self):
show_str = 'Comparison:\n # for each folder:\n\t' + '\n\t'.join(map(str, img_len_list))
self.comparison_label.setText(show_str)
if is_same_len is False:
msg = f'Comparison folders have differnet number of images.\n{show_str}'
msg = f'Comparison folders have different number of images.\n{show_str}'
show_msg('Warning', 'Warning!', msg)

def compare_folders(self, step):
Expand Down Expand Up @@ -239,12 +242,62 @@ def show_image(self, init=False):
md5, phash = self.db.get_fingerprint(fidx=fidx)
md5_0, phash_0 = self.db.get_fingerprint(fidx=self.db.fidx)

qimg = QImage(img_path)
# get LUT and processing
cv2_lut, cv2_lut_name = self.db.get_LUT()
processing = self.db.get_processing()

# None use directly Qt
if cv2_lut == 0 and processing == "None":
# no LUT --> use QImage function
qimg = QImage(img_path) # using Qt to load the image
else:
# Using OpenCV for image processing w/o LUT
if cv2_lut == 0 and processing != "None":
# No LUT but processing (on RGB)
cvimg = cv2.imread(img_path, flags=cv2.IMREAD_COLOR)

# Apply the different processing params
if processing == "Shift 2 Bit":
cvimgproc = cvimg * 4
elif processing == "Histogram equalization":
cvimgyuv = cv2.cvtColor(cvimg, cv2.COLOR_BGR2YUV)
# equalize the histogram of the Y channel
cvimgyuv[:, :, 0] = cv2.equalizeHist(cvimgyuv[:, :, 0])

# convert the YUV image back to RGB format
cvimgproc = cv2.cvtColor(cvimgyuv, cv2.COLOR_YUV2BGR)
else:
cvimgproc = cvimg

# Using OpenCV for image processing w LUT
if cv2_lut != 0:
# using OpenCV to load the image in gray and apply the LUT
cvimg = cv2.imread(img_path, flags=cv2.IMREAD_GRAYSCALE)

# Apply the different processing params
if processing == "Shift 2 Bit":
cvimgproc = cvimg * 4
elif processing == "Histogram equalization":
cvimgproc = cv2.equalizeHist(cvimg)
else:
cvimgproc = cvimg

# Apply LUT
if cv2_lut != 0:
# Apply LUT
lutImg = cv2.applyColorMap(cvimgproc, cv2_lut)
else:
lutImg = cvimgproc

# finally set image for Qt
qimg = QImage(lutImg.data, lutImg.shape[1], lutImg.shape[0], lutImg.strides[0], QImage.Format_RGB888)

self.img_path = img_path
if idx == 0:
# for HVView, HVScene show_mouse_color.
# only work on the first qimg (main canvas mode)
self.qimg = qimg

# show image path in the statusbar
self.parent.set_statusbar(f'{img_path}')

Expand Down Expand Up @@ -275,6 +328,13 @@ def get_parent_dir(path, levels=1):
f'[{shown_idx:d} / {self.db.get_path_len():d}] {tail}', head, f'{height:d} x {width:d}, {file_size}',
f'{color_type}'
]

# Add processing and LUT
if processing != "None":
shown_text.append(" Processing:" + processing)
if cv2_lut != 0:
shown_text.append(" LUT:" + cv2_lut_name)

# show fingerprint
if self.show_fingerprint:
if idx > 0:
Expand All @@ -287,10 +347,11 @@ def get_parent_dir(path, levels=1):
shown_text.append(f'phash: {phash}')

if qview.hasFocus():
color = 'red'
else:
color = 'green'
else:
color = 'red'
qview.set_shown_text(shown_text, color)

# qview.viewport().update()
qpixmap = QPixmap.fromImage(qimg)

Expand Down
15 changes: 11 additions & 4 deletions handyview/canvas_crop.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ def init_widgets_layout(self):
button_open_rect.clicked.connect(self.open_rect_folder)
button_open_history = QPushButton('Open History Info', self)
button_open_history.clicked.connect(self.open_history_file)

button_delete_patch = QPushButton('Delete Patch Folder', self)
button_delete_patch.clicked.connect(self.delete_patch_folder)
button_delete_rect = QPushButton('Delete Rect Folder', self)
Expand All @@ -162,9 +161,9 @@ def init_widgets_layout(self):
action_grid.addWidget(button_open_patch, 4, 0, 1, 1)
action_grid.addWidget(button_open_rect, 5, 0, 1, 1)
action_grid.addWidget(button_open_history, 6, 0, 1, 1)
action_grid.addWidget(HLine(), 7, 0, 1, 1)
action_grid.addWidget(button_delete_patch, 8, 0, 1, 1)
action_grid.addWidget(button_delete_rect, 9, 0, 1, 1)
action_grid.addWidget(HLine(), 8, 0, 1, 1)
action_grid.addWidget(button_delete_patch, 9, 0, 1, 1)
action_grid.addWidget(button_delete_rect, 10, 0, 1, 1)

config_box = QGroupBox('Config')
config_box.setLayout(config_grid)
Expand Down Expand Up @@ -304,5 +303,13 @@ def open_history_file(self):
except Exception as error:
show_msg(icon='Critical', title='Title', text=f'Open error: {error}', timeout=None)

def open_LUT(selfself):
try:
# TODO
show_msg(icon='Info', title='LUT', text='LUT', timeout=None)

except Exception as error:
show_msg(icon='Critical', title='Title', text=f'Open error: {error}', timeout=None)

def keyPressEvent(self, event):
pass
28 changes: 28 additions & 0 deletions handyview/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import imagehash
import os
from PIL import Image, ImageFile
import cv2

from handyview.utils import FORMATS, ROOT_DIR, get_img_list, scandir, sizeof_fmt
from handyview.widgets import show_msg
Expand All @@ -10,6 +11,11 @@
ImageFile.LOAD_TRUNCATED_IMAGES = True
Image.MAX_IMAGE_PIXELS = None

LUT_Names = ["None", "Jet", "Cool", "Hot", "HSV"]
LUT_Values = [0, cv2.COLORMAP_JET, cv2.COLORMAP_COOL, cv2.COLORMAP_HOT, cv2.COLORMAP_HSV]

processing_names = ["None", "Shift 2 Bit", "Histogram equalization"]


class HVDB():
"""HandyView database.
Expand Down Expand Up @@ -45,6 +51,10 @@ def __init__(self, init_path):

self.get_init_path_list()

# LUT
self.use_LUT = "None"
self.useprocessing = "None"

def get_init_path_list(self):
"""get path list when first launch (double click or from cmd)"""
# if init_path is a folder, try to get the first image
Expand Down Expand Up @@ -158,6 +168,24 @@ def get_folder(self, folder=None, fidx=None):
folder = self.folder_list[fidx]
return folder

def get_LUT(self):
if self.use_LUT is None:
self.use_LUT = "None"
cv_lut_name = LUT_Names.index(self.use_LUT)
cv_lut_id = LUT_Values[cv_lut_name]
return cv_lut_id, self.use_LUT

def get_processing(self):
if self.useprocessing is None:
self.useprocessing = "None"
return self.useprocessing

def get_all_LUTs(self):
return LUT_Names

def get_all_processings(self):
return processing_names

def get_path(self, fidx=None, pidx=None):
if fidx is None:
fidx = self._fidx
Expand Down
Loading