You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于OpenCV的Python交互式画圆:实现±键调整半径功能

问题描述

需要实现以下功能:

  • 左键点击绘制圆(已完成)
  • 右键点击更改圆的颜色(已完成)
  • 按'+'键将圆半径增加10
  • 按'-'键将圆半径减少10

现有代码如下:

import cv2
import numpy as np
import random


k = cv2.waitKey(10) & 0xff
def draw_circle(event, x, y, flags, param):
    k1 = cv2.waitKey(10) & 0xff 
    # global radius # just trying idk

    if event == cv2.EVENT_LBUTTONDOWN:
        cv2.circle(img = image, center = (x,y), radius = 50 , 
        color = (255,0,0), thickness = 2)
        print('x = {}, y = {}'.format(x,y))

    elif event == cv2.EVENT_RBUTTONDOWN:
        c1 = random.randint(0, 255)
        c2 = random.randint(0, 255)
        c3 = random.randint(0, 255)

        cv2.circle(img = image, center = (x,y), radius = 100, 
        color = (c1, c2, c3), thickness = 2)


image = np.zeros((600,600,3), dtype = np.uint8)

cv2.namedWindow(winname = 'testwindow')
cv2.setMouseCallback('testwindow',draw_circle)

while True:
    cv2.imshow('testwindow',image)
    if k == 32:
         print('Something') 
    k = cv2.waitKey(1)
    if k == 27:
        break

cv2.destroyAllWindows() 
解决方案

要实现按键调整半径的功能,核心是把半径设为全局变量,在主循环中监听按键事件修改它,同时让鼠标绘制逻辑使用这个全局半径。具体修改步骤如下:

  1. 定义全局半径变量:初始化一个默认半径值,让鼠标事件函数和主循环都能访问它
  2. 主循环中监听按键:通过cv2.waitKey()获取按键码,判断是否为'+'或'-',调整半径时限制最小值避免异常
  3. 修改鼠标绘制逻辑:把原来固定的半径数值替换成全局变量

修改后的完整代码:

import cv2
import numpy as np
import random

# 全局半径变量,初始化默认值
radius = 50

def draw_circle(event, x, y, flags, param):
    global radius  # 声明使用全局变量

    if event == cv2.EVENT_LBUTTONDOWN:
        # 使用全局radius绘制蓝色圆
        cv2.circle(img=image, center=(x,y), radius=radius, 
                   color=(255,0,0), thickness=2)
        print(f'x = {x}, y = {y}, 当前半径: {radius}')

    elif event == cv2.EVENT_RBUTTONDOWN:
        # 生成随机颜色
        c1 = random.randint(0, 255)
        c2 = random.randint(0, 255)
        c3 = random.randint(0, 255)
        # 使用全局radius绘制随机颜色圆
        cv2.circle(img=image, center=(x,y), radius=radius, 
                   color=(c1, c2, c3), thickness=2)


image = np.zeros((600,600,3), dtype=np.uint8)

cv2.namedWindow(winname='testwindow')
cv2.setMouseCallback('testwindow', draw_circle)

while True:
    cv2.imshow('testwindow', image)
    k = cv2.waitKey(1) & 0xff  # 处理跨平台按键兼容性
    
    if k == 27:  # ESC键退出程序
        break
    elif k == 43:  # '+'键的ASCII码为43
        radius += 10
        print(f'半径已增加,当前半径: {radius}')
    elif k == 45:  # '-'键的ASCII码为45
        if radius > 10:  # 限制半径最小值,避免无法绘制
            radius -= 10
            print(f'半径已减少,当前半径: {radius}')
        else:
            print('半径不能再小了!')

cv2.destroyAllWindows()

关键说明

  • global radius:必须在鼠标事件函数内声明,否则函数会创建局部变量覆盖全局值
  • 按键码判断:直接使用ASCII码判断'+'和'-',避免因输入法或系统差异导致的识别问题
  • 半径限制:添加最小值判断,防止半径变为0或负数导致绘制异常

内容的提问来源于stack exchange,提问作者Giqs CB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 20:05:39