未验证 提交 d986e8fc 编写于 作者: A alexander-g 提交者: GitHub

Added a tool to adjust image brightness and contrast. Useful for dark images (#494)

* Added a tool to adjust image brightness and contrast. Useful for dark images.

* Refactor brightness and contrast adjuster

* Fix syntax error in Python2
Co-authored-by: NKentaro Wada <www.kentaro.wada@gmail.com>
上级 9a815742
......@@ -22,6 +22,7 @@ from labelme.label_file import LabelFile
from labelme.label_file import LabelFileError
from labelme.logger import logger
from labelme.shape import Shape
from labelme.widgets import BrightnessContrastDialog
from labelme.widgets import Canvas
from labelme.widgets import LabelDialog
from labelme.widgets import LabelListWidget
......@@ -401,6 +402,11 @@ class MainWindow(QtWidgets.QMainWindow):
shortcuts['fit_width'], 'fit-width',
self.tr('Zoom follows window width'),
checkable=True, enabled=False)
brightnessContrast = action('&Brightness Contrast',
self.brightnessContrast,
None, 'color',
'Adjust brightness and contrast',
enabled=False)
# Group zoom controls into a list for easier toggling.
zoomActions = (self.zoomWidget, zoomIn, zoomOut, zoomOrg,
fitWindow, fitWidth)
......@@ -455,6 +461,7 @@ class MainWindow(QtWidgets.QMainWindow):
createLineStripMode=createLineStripMode,
zoom=zoom, zoomIn=zoomIn, zoomOut=zoomOut, zoomOrg=zoomOrg,
fitWindow=fitWindow, fitWidth=fitWidth,
brightnessContrast=brightnessContrast,
zoomActions=zoomActions,
openNextImg=openNextImg, openPrevImg=openPrevImg,
fileMenuActions=(open_, opendir, save, saveAs, close, quit),
......@@ -498,6 +505,7 @@ class MainWindow(QtWidgets.QMainWindow):
createPointMode,
createLineStripMode,
editMode,
brightnessContrast,
),
onShapesPresent=(saveAs, hideAll, showAll),
)
......@@ -554,6 +562,7 @@ class MainWindow(QtWidgets.QMainWindow):
fitWindow,
fitWidth,
None,
brightnessContrast,
),
)
......@@ -584,6 +593,7 @@ class MainWindow(QtWidgets.QMainWindow):
copy,
delete,
undo,
brightnessContrast,
None,
zoomIn,
zoom,
......@@ -1238,6 +1248,16 @@ class MainWindow(QtWidgets.QMainWindow):
self.zoomMode = self.FIT_WIDTH if value else self.MANUAL_ZOOM
self.adjustScale()
def brightnessContrast(self, value):
def onNewBrightnessContrast(qimage):
self.canvas.loadPixmap(QtGui.QPixmap.fromImage(qimage),
clear_shapes=False)
dialog = BrightnessContrastDialog(
self.filename, onNewBrightnessContrast, parent=self)
dialog.exec_()
def togglePolygons(self, value):
for item in self.labelList:
item.setCheckState(Qt.Checked if value else Qt.Unchecked)
......
# flake8: noqa
from .brightness_contrast_dialog import BrightnessContrastDialog
from .canvas import Canvas
from .color_dialog import ColorDialog
......
from qtpy.QtCore import Qt
from qtpy import QtGui
from qtpy import QtWidgets
from PIL import Image
from PIL import ImageEnhance
class BrightnessContrastDialog(QtWidgets.QDialog):
def __init__(self, filename, callback, parent=None):
super(BrightnessContrastDialog, self).__init__(parent)
self.setModal(True)
self.setWindowTitle('Brightness/Contrast')
self.slider_brightness = self._create_slider()
self.slider_contrast = self._create_slider()
formLayout = QtWidgets.QFormLayout()
formLayout.addRow(self.tr('Brightness'), self.slider_brightness)
formLayout.addRow(self.tr('Contrast'), self.slider_contrast)
self.setLayout(formLayout)
self.img = Image.open(filename).convert('RGBA')
self.callback = callback
def onNewValue(self, value):
brightness = self.slider_brightness.value() / 100.
contrast = self.slider_contrast.value() / 100.
img = self.img
img = ImageEnhance.Brightness(img).enhance(brightness)
img = ImageEnhance.Contrast(img).enhance(contrast)
bytes = img.tobytes('raw', 'RGBA')
qimage = QtGui.QImage(bytes,
img.size[0], img.size[1],
QtGui.QImage.Format_RGB32).rgbSwapped()
self.callback(qimage)
def _create_slider(self):
slider = QtWidgets.QSlider(Qt.Horizontal)
slider.setRange(0, 300)
slider.setValue(100)
slider.valueChanged.connect(self.onNewValue)
return slider
......@@ -708,9 +708,10 @@ class Canvas(QtWidgets.QWidget):
self.drawingPolygon.emit(False)
self.repaint()
def loadPixmap(self, pixmap):
def loadPixmap(self, pixmap, clear_shapes=True):
self.pixmap = pixmap
self.shapes = []
if clear_shapes:
self.shapes = []
self.repaint()
def loadShapes(self, shapes, replace=True):
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册