首先设计UI界面, 调整自己满意的布局. 其中黑色为 QLabel, 对象名为labelImage, 用于显示图像. 左下角为拖动条, 对称为sliderThreshold, 用于修改参数. Open按钮用于打开文件, 对象名为openButton. 在界面编辑器中, 将Close按钮的clicked信号连接到窗口的close槽.
窗口设计完成后保存到edge.ui, 然后基于edge.ui文件构造程序:
# -*- coding:utf-8 -*-
###########################################################
# PyQt+OpenCV example
#
# 查找图像中的边界.
# 参考 OpenCV\samples\python\edge.py 改写
#
# By chaishushan{AT}gmail.com 2008
###########################################################
import sys
# 导入PyQt模块
from PyQt4.Qt import *
from PyQt4 import uic
# 导入OpenCV模块
from opencv.cv import *
from opencv.highgui import *
# 边界检测类
class WinEdge(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
uic.loadUi("edge.ui", self)
# OpenCV相关参数
self.cv_img = None
self.cv_col_edge = None
self.cv_gray = None
self.cv_edge = None
# 标题
self.defaultTitle = self.windowTitle()
@pyqtSignature("")
def on_openButton_clicked(self):
filename = QFileDialog.getOpenFileName(self,
self.tr("Choose a Image"), ".",
self.tr("Image Files (*.jpg;*.bmp);;All Files (*)"))
if not filename.isEmpty():
self.sliderThreshold.setEnabled(False)
self.openImage(filename)
self.dectorEdge(self.sliderThreshold.value())
# 更新UI
if self.cv_col_edge:
self.setWindowTitle(filename)
self.sliderThreshold.setEnabled(True)
else:
self.setWindowTitle(self.defaultTitle)
self.sliderThreshold.setEnabled(False)
@pyqtSignature("int")
def on_sliderThreshold_valueChanged(self, val):
# 重新计算边界
self.dectorEdge(val)
def resizeEvent(self, event):
self.showImage()
# 打开图像
def openImage(self, qstringName):
# 将QString转换为char *
filename = qstringName.toLocal8Bit().data()
# 释放以前的图像
if self.cv_img :
cvReleaseImage( self.cv_img ); self.cv_img = None
cvReleaseImage( self.cv_col_edge ); self.cv_col_edge = None
cvReleaseImage( self.cv_gray ); self.cv_gray = None
cvReleaseImage( self.cv_edge ); self.cv_edge = None
# 打开新的图像
self.cv_img = cvLoadImage(filename)
if not self.cv_img:
msg = self.tr("Can't open %1 file!").arg(filename)
QMessageBox.warning (self, "Warning", msg)
return False
# 创建辅助空间
size = cvSize(self.cv_img.width, self.cv_img.height)
self.cv_col_edge = cvCreateImage (size, 8, 3)
self.cv_gray = cvCreateImage (size, 8, 1)
self.cv_edge = cvCreateImage (size, 8, 1)
return True
# 生成边界
def dectorEdge(self, position):
if not self.cv_img: return
# 转换为灰度
cvCvtColor (self.cv_img, self.cv_gray, CV_BGR2GRAY)
cvSmooth (self.cv_gray, self.cv_edge, CV_BLUR, 3, 3, 0)
cvNot (self.cv_gray, self.cv_edge)
# run the edge dector on gray scale
cvCanny (self.cv_gray, self.cv_edge, position, position * 3, 3)
# 结构保存到cv_col_edge中
cvSetZero (self.cv_col_edge)
cvCopy (self.cv_img, self.cv_col_edge, self.cv_edge)
# 显示
self.showImage()
# 显示图像
def showImage(self):
if not self.cv_col_edge: return
# 转化IplImage为QImage
w = self.cv_col_edge.width
h = self.cv_col_edge.height
step = self.cv_col_edge.widthStep
data = self.cv_col_edge.imageData
img = QImage(data, w, h, step, QImage.Format_RGB888).rgbSwapped()
# 显示图像[缩放到窗口大小]
size = self.labelImage.size()
self.labelImage.setPixmap(QPixmap.fromImage(img.scaled(size)))
if __name__ == '__main__':
app = QApplication(sys.argv)
widget = WinEdge()
widget.show()
app.exec_()
运行结果如图:
完整的代码以后补充。