opencv 实现ps油漆桶【二】

该博客介绍了一个使用Python和OpenCV实现的简易画板工具,用户可以通过鼠标绘制图形。程序允许用户在画板上进行自由绘画,并保存为前景图像。代码实现了鼠标事件监听,包括按下、移动和抬起,支持圆圈绘制模式。最终,用户可以将画布保存为黑白或原始格式的图像文件供算法实验使用。
摘要由CSDN通过智能技术生成

github地址(更新中):https://github.com/SunnyWuYang/Paint-Bucket-with-Gaps

参考:
[1] opencv实现画板效果:
https://blog.csdn.net/qq_42191914/article/details/105035921

版本二目的与功能:

  1. 创建简易版的画板工具为算法提供实验图像
  2. 利用自己绘制的图像测试算法

算法实现

import os
import sys
import cv2
import numpy as np

"""
TODO list in future versions:
1. add button and label
2. refactor code
"""


class Painter:
    """
    默认情况下,程序为绘画模式,即按下鼠标左键后并拖动可以进行绘制。
    -退出按'q'   
    """

    def __init__(self, img_size=(600, 800, 3), circle_radius=8, win_name='my Drawing Board', save_path=None, color=(1, 1, 255)):
        """
        :param img_size:画板大小,若指定background则忽略此参数
        :param circle_radius:‘circle'模式下圆形的半径
        :param win_name:窗口名
        :param save_path:绘图结果保存地址
        :param color:画笔颜色

        """
        self.win_name = win_name
        self.save_path = save_path
        self.brush_color = color
        self.circle_radius = circle_radius

        self.layer_back = np.ones(
            img_size, dtype=np.uint8)
        self.layer_back = self.layer_back*255

        # 鼠标是否产生了一次“按下—松开”的click过程
        self.click = False
        # 是否处于绘制状态
        self.drawing = False

        self.x2, self.y2 = -1, -1   # (circle模式)记录"circle"模式且未绘制状态下,鼠标上次的位置

    def saveForeground(self, save_path, mode='black_mask'):
        """
        当使用background时,保存前景图像
        :param save_path: 前景图像保存地址
        :param mode:模式,'raw'按原前景图存,'black_mask'则按黑白格式存(被画的地方为黑,其余地方为白),'white_mask'相反
        :return:
        """
        # TODO 实现其余的mode
        if mode == 'black_mask':
            # 初始化为全白
            fore = np.ones(shape=self.layer_back.shape,
                           dtype=np.uint8)
            fore = fore*255
            fore[(self.layer_back[:, :] == np.array(self.brush_color)).all(
                axis=2)] = np.array([0, 0, 0])  # 被画的地方设为全黑
            cv2.imwrite(save_path, fore)
        else:
            print("模式错误!")
            sys.exit(0)

    def mouseEvent(self, event, x, y, flag, param):
        # (1)鼠标左键按下事件——开启绘图状态
        if event == cv2.EVENT_LBUTTONDOWN:
            self.drawing = True
            self.x2, self.y2 = -1, -1
        # (2)鼠标移动事件——绘图
        elif event == cv2.EVENT_MOUSEMOVE:
            if self.drawing:  # 点击后未抬起的移动
                cv2.circle(self.layer_back, (x, y), radius=self.circle_radius,
                           color=self.brush_color,
                           thickness=-1)

        # (3)鼠标左键抬起事件——结束绘图状态
        elif event == cv2.EVENT_LBUTTONUP:
            self.drawing = False
            self.click = True

    def main(self):
        cv2.namedWindow(self.win_name, cv2.WINDOW_NORMAL)
        cv2.setMouseCallback(self.win_name, self.mouseEvent)  # 鼠标事件回调函数
        while True:
            cv2.imshow(self.win_name, self.layer_back)
            key = cv2.waitKey(1)
            if key == ord('q'):
                print("The windows are destroyed")
                break
        if self.save_path:
            self.saveForeground(self.save_path)
        cv2.destroyAllWindows()


if __name__ == '__main__':
    painter = Painter(img_size=(150, 200, 3),
                      circle_radius=4,
                      save_path='layer_back.png',
                      color=(0, 0, 255))
    painter.main()

测试

if __name__ == '__main__':
    img = cv2.imread(
        'layer_back.png', 0)
    img = np.array(img, dtype=np.uint8)
    img[img > 0] = 1

    seedX = 65
    seedY = 83
    gap = 10
    result = floodfill_with_gap(img, seedX, seedY, gap)
    cv2.imwrite('result.png', result*255)

左:画图效果;中:储存结果;右:算法处理结果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值