共计 2372 个字符,预计需要花费 6 分钟才能阅读完成。
PyQt5 画图板
次要技术
- PyQt5
- qtDesigner
- openCV
次要性能
-
绘画
- 画笔
- 油漆桶
- 直线
- 矩形
- 椭圆
- 橡皮擦
-
图片解决
- 旋转、翻转
- 亮度、饱和度、对比度、色调调节
- 灰度化
- 二值化
- 反相(反色)
- 浮雕
- 边缘检测
- 含糊
- 锐化
具体代码
github 仓库
实现过程遇到的问题
在 pycharm 上应用 qtDesigner
配置 qtDesigner
配置 UIC
参考 Mac 下 pycharm+qtdesigner 环境搭建
绘图时图像不能留存或重影问题
采取双缓冲绘图办法
咱们再增加一个辅助画布,如果正在绘图,也就是鼠标按键还没有开释的时候,就在这个辅助画布上绘图,只有当鼠标按键开释的时候,才在真正的画布上绘图
参考 2D 绘图(八)双缓冲绘图
油漆桶 Flood Fill 算法问题
泛洪算法—Flood Fill,用于确定连贯到多维数组中给定节点的区域。
基本原理就是从一个像素点登程,以此向周边的像素点裁减着色,直到图形的边界。
实现办法包含传统递归形式 dfs、bfs 和描述线算法 (Scanline Fill) 等
在 QImage 上实现效率很低,因为 getPixel 操作很慢,能够进一步优化
def getPixel(x,y,pixels,w):
i = (x + (y * w)) * 4
return pixels[i:i + 3]
# 油漆桶
def floodFill(image,pos):
fillPositions = []
w, h = image.width(), image.height()
pixels = image.bits().asstring(w * h * 4)
targetColor = getPixel(pos.x(), pos.y(), pixels, w)
haveSeen = set()
queue = [(pos.x(), pos.y())]
while queue:
x, y = queue.pop()
if getPixel(x, y,pixels,w) == targetColor:
fillPositions.append((x,y))
queue.extend(getCardinalPoints(haveSeen, (x, y),w,h))
return fillPositions
def getCardinalPoints(haveSeen, centerPos,w,h):
points = []
cx, cy = centerPos
for x, y in [(1, 0), (0, 1), (-1, 0), (0, -1)]:
xx, yy = cx + x, cy + y
if (xx >= 0 and xx < w and yy >= 0 and yy < h and (xx, yy) not in haveSeen):
points.append((xx, yy))
haveSeen.add((xx, yy))
return points
参考 Implementing QPainter flood fill in PyQt5/PySide
图像宰割经典算法 –《泛洪算法》(Flood Fill)
Mac 上 pyqt5 与 cv 库抵触问题
问题You might be loading **two sets of Qt binaries** into the same process
删除原有的 opencv
pip3 uninstall opencv-python
装置 opencv–headless 版本
pip3 install opencv-contrib-python-headless
参考 Mac 下应用 opencv 与 pyqt 发生冲突
pyqt QImage 与 opencv MAT 格局转化问题
在应用 opencv 过程中须要传入 QImage 对象进行解决
QImage 转化成 opencv 下的 MAT(numpy ndarray) 对象
def CvMatToQImage(cvMat):
if len(cvMat.shape) == 2:
rows, columns = cvMat.shape
bytesPerLine = columns
return QImage(cvMat.data, columns, rows, bytesPerLine, QImage.Format_Indexed8)
else:
rows, columns, channels = cvMat.shape
bytesPerLine = channels * columns
return QImage(cvMat.data, columns, rows, bytesPerLine, QImage.Format_RGBA8888)
MAT(numpy ndarray) 转 QImage
def QImageToCvMat(incomingImage):
incomingImage = incomingImage.convertToFormat(QImage.Format_RGBA8888)
width = incomingImage.width()
height = incomingImage.height()
ptr = incomingImage.bits()
ptr.setsize(height * width * 4)
arr = np.frombuffer(ptr, np.uint8).reshape((height, width, 4))
return arr
参考 Python 中如何将 Pyqt5 下的 QImage 对象转换成 PIL image 或 opencv MAT (numpy ndarray) 对象
成果预览
绘画
油漆桶成果
图像处理局部展现
原图
亮度调节
色调调节
反相
灰度化
二值化
边缘检测
局部参考
https://www.cnblogs.com/lfri/p/10599420.htmlhttps://blog.csdn.net/qq_43444349/article/details/106602543
https://www.pianshen.com/article/172962944/
https://blog.csdn.net/lzwarhang/article/details/93209166