程序采用PySide窗口框架实现窗体,先看运行效果:
通过窗体下方三个滚动条可分别调节图像红、绿、蓝三个颜色通道的增减值,以达到调节图像三个颜色通道的亮度。
设计思路:
在窗体类中定义一元组类型的成员变量:adj_value,其有三个元素,分别对应图像红、绿、蓝三个通道的校正值;每个校正值的变化范围为-255至255之间,对应下方三个滚动条的取值范围;这样即可改变任意一个通道的颜色分量的亮度,也可三个通道一起改变相同的值,这样就等于改变了图像的整体亮度。
self.adj_value=(0,0,0) #亮度校正值对应(r,g,b)三元色的校正值,若三值相同则为改变图像亮度
而改变图像的三个颜色分量的具体办法为:将图像的每个像素值的三分量(r,g,b)加上adj_value(r,g,b)的值,如果某个分量值大于255,则分量值取255;如果某个分量值小于0,则分量值取0;
具体实现:
在qt设计师里设置好窗口控件与布局:
入口程序:main.py
from PySide2.QtWidgets import QApplication
from mainForm import MainForm
if __name__ == "__main__":
app = QApplication([])
mainForm = MainForm()
mainForm.ui.show()
app.exec_()
窗体主程序:mainForm.py
from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import QMessageBox, QFileDialog
from PySide2.QtGui import QPixmap,QImage
from matplotlib.pyplot import imread,imsave
import numpy as np
import os
class MainForm:
def __init__(self):
# 从文件中加载UI定义
# 从 UI 定义中动态 创建一个相应的窗口对象
# 注意:里面的控件对象也成为窗口对象的属性了
# 比如 self.ui.button , self.ui.textEdit
self.ui = QUiLoader().load('ui\mainForm.ui')
self.adj_value=(0,0,0) #亮度校正值对应(r,g,b)三元色的校正值,若三值相同则为改变图像亮度
fname = "images/original.bmp"
self.image = np.array(imread(fname))
self.process_image=self.image
showImage = QImage(self.image.data, self.image.shape[1], self.image.shape[0], QImage.Format_RGB888)
#下面两行设置Qlabel的宽和高
self.ui.label.setFixedWidth(self.image.shape[1])
self.ui.label.setFixedHeight(self.image.shape[0])
self.ui.label.setPixmap(QPixmap.fromImage(showImage))
# self.ui.label.setScaledContents(True) # 让图片自适应 label 大小
self.ui.pushButton_2.clicked.connect(self.openPic)
self.ui.pushButton_3.clicked.connect(self.savePic)
self.ui.pushButton.clicked.connect(self.handleReset)
#连接滚动条事件处理槽函数
self.ui.horizontalScrollBar.valueChanged.connect(self.slidermove)
self.ui.horizontalScrollBar_2.valueChanged.connect(self.slidermove)
self.ui.horizontalScrollBar_3.valueChanged.connect(self.slidermove)
def openPic(self):
curDir=os.getcwd()
fname=QFileDialog.getOpenFileName(
self.ui,
"打开图像文件",
curDir,
"所有图像文件 (*.jpg *.bmp)"
)
self.image = np.array(imread(fname[0]))
self.process_image=self.image
showImage = QImage(self.image.data, self.image.shape[1], self.image.shape[0], QImage.Format_RGB888)
width=self.image.shape[1]
height=self.image.shape[0]
if width>900:
width=width / 3
height=height / 3
self.ui.label.setFixedWidth(width)
self.ui.label.setFixedHeight(height)
self.ui.label.setPixmap(QPixmap.fromImage(showImage))
self.ui.label.setScaledContents(True) # 让图片自适应 label 大小
self.handleReset()
def savePic(self):
fileDialog = QFileDialog(self.ui)
# getSaveFileName 这是一个方便的静态函数,它将返回用户选择的文件名。该文件不必存在
fileName=fileDialog.getSaveFileName(self.ui,'保存文件','','Jpg 格式 (*.jpg);; All files (*)')
# print(fileName)
imsave(fileName[0],self.process_image)
def slidermove(self,value):
r_adjValue = self.ui.horizontalScrollBar.value()
g_adjValue = self.ui.horizontalScrollBar_2.value()
b_adjValue = self.ui.horizontalScrollBar_3.value()
self.adj_value=(r_adjValue,g_adjValue,b_adjValue)
self.ui.label_5.setText(str(r_adjValue))
self.ui.label_6.setText(str(g_adjValue))
self.ui.label_7.setText(str(b_adjValue))
self.picProcess()
def picProcess(self):
image = self.image.astype(np.int16)
image = image + self.adj_value # 校正三元色值都为相同的正值为加亮图像,反之都为相同的负值就是变暗图像
image[image > 255] = 255 # 注意这里的用法--将值大于255的数值置为255
image[image < 0] = 0 # 注意这里的用法--将值小于0的设为0
image=image.astype(np.uint8)
self.process_image=image
showImage = QImage(image.data, image.shape[1], image.shape[0], QImage.Format_RGB888)
self.ui.label.setPixmap(QPixmap.fromImage(showImage))
def handleReset(self):
self.adj_value=(0,0,0)
self.ui.horizontalScrollBar.setValue(0)
self.ui.horizontalScrollBar_2.setValue(0)
self.ui.horizontalScrollBar_3.setValue(0)
这里需强调的是,我是用myplotlib.pyplot模块中的imread读入图像,图像的处理是在picProcess函数中完成的;读入图像后用np.array()将图像转为numpy数组,这样方便图像中对每个像素的计算,但注意的是,np.array方法默认将像素值作为无符号整型uint8处理的,但实际计算中像素值有可能会小于0或大于255,所以计算前astype方法将像素值转为int16型,计算完成之后再转为uint8,以保证图像的正常显示;在Qlabel控件中显示图像,要将图像转为Qimage类型,再转为QPixmap类型。而保存图像是用了pyplot模块里的imsave......这些细节就不复述了,自行参阅代码。
其它:
项目列表
至于窗口中控件的使用、事件处理、图像打开与保存等请自行参阅代码,这里就不多介绍了。