提交 f319cb1c 编写于 作者: F feilong

add doodle

上级 9dfe922e
{
"type": "code_options",
"author": "huanhuilong",
"source": "doodle.md",
"notebook_enable": true
}
\ No newline at end of file
# 矩形涂鸦画板
![](./doodle.png)
编写一个矩形涂鸦画板,实现功能:
* 鼠标左键按下拖动绘制矩形,鼠标左键弹起时完成绘制
*`'c'`键清空画板
*`'ESC'`键退出
基本框架代码如下:
```python
import numpy as np
import cv2 as cv
from random import randint
class Painter:
def __init__(self) -> None:
self.mouse_is_pressed = False
self.last_pos = (-1, -1)
self.width = 300
self.height = 512
self.img = np.zeros((self.width, self.height, 3), np.uint8)
self.window_name = 'painter'
self.color = None
def run(self):
print('画板,拖动鼠标绘制矩形框,按ESC退出,按c键清空画板')
cv.namedWindow(self.window_name)
cv.setMouseCallback(
self.window_name,
lambda event, x, y, flags, param: self.on_draw(
event, x, y, flags, param
)
)
while True:
cv.imshow(self.window_name, self.img)
k = cv.waitKey(1) & 0xFF
if k == ord('c'):
self.clean()
elif k == 27:
break
cv.destroyAllWindows()
def on_draw(self, event, x, y, flags, param):
# TODO(You): 请正确实现画板事件响应,完成功能
def clean(self):
cv.rectangle(self.img, (0, 0),
(self.height, self.width), (0, 0, 0), -1)
def begin_draw_rectangle(self, pos1, pos2):
if self.color is None:
self.color = (randint(0, 256), randint(0, 256), randint(0, 256))
cv.rectangle(self.img, pos1, pos2, self.color, -1)
def end_draw_rectangle(self, pos1, pos2):
self.color = None
if __name__ == '__main__':
p = Painter()
p.run()
```
以下正确实现鼠标事件,完成画板绘制逻辑的代码是?
## 答案
```python
pos = (x, y)
if event == cv.EVENT_LBUTTONDOWN:
self.mouse_is_pressed = True
self.last_pos = pos
elif event == cv.EVENT_MOUSEMOVE:
if self.mouse_is_pressed == True:
self.begin_draw_rectangle(self.last_pos, pos)
elif event == cv.EVENT_LBUTTONUP:
self.end_draw_rectangle(self.last_pos, pos)
self.mouse_is_pressed = False
```
## 选项
### 鼠标移动事件里缺乏判断
```python
pos = (x, y)
if event == cv.EVENT_LBUTTONDOWN:
self.mouse_is_pressed = True
self.last_pos = pos
elif event == cv.EVENT_MOUSEMOVE:
self.begin_draw_rectangle(self.last_pos, pos)
elif event == cv.EVENT_LBUTTONUP:
self.end_draw_rectangle(self.last_pos, pos)
self.mouse_is_pressed = False
```
### 鼠标按下事件里缺乏标记
```python
pos = (x, y)
if event == cv.EVENT_LBUTTONDOWN:
self.last_pos = pos
elif event == cv.EVENT_MOUSEMOVE:
if self.mouse_is_pressed == True:
self.begin_draw_rectangle(self.last_pos, pos)
elif event == cv.EVENT_LBUTTONUP:
self.end_draw_rectangle(self.last_pos, pos)
self.mouse_is_pressed = False
```
### 鼠标按起时忘记清空标记
```python
pos = (x, y)
if event == cv.EVENT_LBUTTONDOWN:
self.mouse_is_pressed = True
self.last_pos = pos
elif event == cv.EVENT_MOUSEMOVE:
if self.mouse_is_pressed == True:
self.begin_draw_rectangle(self.last_pos, pos)
elif event == cv.EVENT_LBUTTONUP:
self.end_draw_rectangle(self.last_pos, pos)
```
import numpy as np
import cv2 as cv
from random import randint
class Painter:
def __init__(self, background, color) -> None:
def __init__(self) -> None:
self.mouse_is_pressed = False
self.last_pos = (-1, -1)
self.img = np.zeros((300, 512, 3), np.uint8)
self.background = background
self.color = color
self.title = '画板,拖动鼠标绘制矩形框,按ESC退出'
self.width = 300
self.height = 512
self.img = np.zeros((self.width, self.height, 3), np.uint8)
self.window_name = 'painter'
self.color = None
def run(self):
cv.namedWindow(self.window_name, title=self.title)
cv.setMouseCallback(self.window_name, lambda event, x, y,
flags, param: self.draw_circle(event, x, y, flags, param))
while(1):
print('画板,拖动鼠标绘制矩形框,按ESC退出,按c键清空画板')
cv.namedWindow(self.window_name)
cv.setMouseCallback(
self.window_name,
lambda event, x, y, flags, param: self.on_draw(
event, x, y, flags, param
)
)
while True:
cv.imshow(self.window_name, self.img)
k = cv.waitKey(1) & 0xFF
if k == 27:
if k == ord('c'):
self.clean()
elif k == 27:
break
cv.destroyAllWindows()
def draw_circle(self, event, x, y, flags, param):
current_pos = (x, y)
def on_draw(self, event, x, y, flags, param):
pos = (x, y)
if event == cv.EVENT_LBUTTONDOWN:
self.mouse_is_pressed = True
self.last_pos = current_pos
self.last_pos = pos
elif event == cv.EVENT_MOUSEMOVE:
if self.mouse_is_pressed == True:
cv.rectangle(self.img, self.last_pos,
current_pos, (0, 255, 0), -1)
self.begin_draw_rectangle(self.last_pos, pos)
elif event == cv.EVENT_LBUTTONUP:
self.end_draw_rectangle(self.last_pos, pos)
self.mouse_is_pressed = False
cv.rectangle(self.img, self.last_pos, current_pos, (0, 255, 0), -1)
def clean(self):
cv.rectangle(self.img, (0, 0),
(self.height, self.width), (0, 0, 0), -1)
def begin_draw_rectangle(self, pos1, pos2):
if self.color is None:
self.color = (randint(0, 256), randint(0, 256), randint(0, 256))
cv.rectangle(self.img, pos1, pos2, self.color, -1)
def end_draw_rectangle(self, pos1, pos2):
self.color = None
if __name__ == '__main__':
p = Painter(background=(100, 100, 100), color=(200, 150, 50))
p = Painter()
p.run()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册