opencv-python通过鼠标点击图片获取该点坐标2,划分多个区域

Posted 辉煌zzg

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了opencv-python通过鼠标点击图片获取该点坐标2,划分多个区域相关的知识,希望对你有一定的参考价值。

之前的博客写了一篇,从图像上通过鼠标点击获取坐标区域,并填充颜色,

 如果需要我们选择的区域继续划分成不同区域,是不是能检测更多内容,比如那一块区域通过的人数最多。

先来回顾之前的代码

import cv2
import numpy as np
 
img = cv2.imread('6.jpg')   #加载本地的图像
img2 = img.copy()
a = []              #用于存放横坐标
b = []              #用于存放纵坐标
 
print('请随意点击3个以上坐标:')
#定义点击事件
def on_EVENT_LBUTTONDOWN(event, x, y,flags, param):
    if event == cv2.EVENT_LBUTTONDOWN:     #如果存在鼠标点击事件
        xy = "%d,%d" % (x, y)              #得到坐标x,y
        a.append(x)     #将每次的坐标存放在a数组里面
        b.append(y)      #将每次的坐标存放在b数组里面
        cv2.circle(img, (x, y), 1, (0, 0, 255), thickness=-1)  #点击的地方小红圆点显示
        cv2.putText(img, xy, (x, y), cv2.FONT_HERSHEY_PLAIN,     #点击的地方显示坐标数字 参数1图片,参数2添加的文字,参数3左上角坐标,参数4字体,参数5字体粗细
                    1.0, (0, 0, 0), thickness=1)
        cv2.imshow("image", img)    #显示图片
 
 
 
cv2.namedWindow("image")             #定义图片窗口
cv2.setMouseCallback("image", on_EVENT_LBUTTONDOWN)   #回调函数,参数1窗口的名字,参数2鼠标响应函数
cv2.imshow("image", img)            #显示图片
cv2.waitKey(0)
 
c = []          #用于存放所有坐标
for i in range(0,len(a)):
    print(a[i], b[i])  # 打印坐标
    c.append([a[i], b[i]])
    print(c)
 
if len(c)<3:
    print('请重新运行,并点击3个以上坐标……')
else:
    h, w = img.shape[:2]  # #显示获取读取进来的图片长宽
    mask = np.zeros((h, w), dtype=np.uint8)     #创建一个等图像大小的全黑背景
    ndarray_pts= np.array(c, np.int32)  # 将坐标数组转化成矩阵
    fill_img = cv2.fillPoly(mask, [ndarray_pts], color = 1)   #对所在区域进行填充颜色,参数二为上面获得的坐标矩阵, 参数3为填充颜色
    fill_img = fill_img[:, :, np.newaxis]  # np.newaxis用于增加第三维的维度
    fill_img = np.array(fill_img * [255, 255, 255], np.uint8)   #转化3维矩阵
    fill_img = cv2.add(img2, fill_img)    #将两个图片像素相加
    cv2.imshow("image2", fill_img)
    cv2.imwrite('1.jpg',fill_img)
    cv2.waitKey(0)

现在我们的坐标区域只选择4个坐标点为研究对象,分别划分不同区域

比如我现在划分成一行3列

 选择4个坐标点之后,再将坐标区域划分成3等分,不同颜色表示

代码如下:

import cv2
import numpy as np

img = cv2.imread('6.jpg')  # 加载本地的图像
img2 = img.copy()
a = []  # 用于存放横坐标
b = []  # 用于存放纵坐标

print('请随意点击3个以上坐标:')


# 定义点击事件
def on_EVENT_LBUTTONDOWN(event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDOWN:  # 如果存在鼠标点击事件
        xy = "%d,%d" % (x, y)  # 得到坐标x,y
        a.append(x)  # 将每次的坐标存放在a数组里面
        b.append(y)  # 将每次的坐标存放在b数组里面
        cv2.circle(img, (x, y), 1, (0, 0, 255), thickness=-1)  # 点击的地方小红圆点显示
        cv2.putText(img, xy, (x, y), cv2.FONT_HERSHEY_PLAIN,  # 点击的地方显示坐标数字 参数1图片,参数2添加的文字,参数3左上角坐标,参数4字体,参数5字体粗细
                    1.0, (0, 0, 0), thickness=1)
        cv2.imshow("image", img)  # 显示图片


cv2.namedWindow("image")  # 定义图片窗口
cv2.setMouseCallback("image", on_EVENT_LBUTTONDOWN)  # 回调函数,参数1窗口的名字,参数2鼠标响应函数
cv2.imshow("image", img)  # 显示图片
cv2.waitKey(0)

c = []  # 用于存放所有坐标
for i in range(0, len(a)):
    print(a[i], b[i])  # 打印坐标
    c.append([a[i], b[i]])
    print(c)
l0 = (c[2][0] - c[1][0]) // 3  #用于加横向距离使用
l1 = (c[3][0] - c[0][0])//3  #用于加横向距离使用
l2 = (c[2][1] - c[1][1])//3   #用于加纵向距离使用
l3 = (c[3][1] - c[0][1])//3   #用于加纵向距离使用
d = []  #用于存放划分的每部分区域
d.append([[c[0][0],c[0][1]],[c[1][0],c[1][1]],[c[1][0]+l0,c[1][1]+l2],[c[0][0]+l1,c[0][1]+l3]])
d.append([[c[0][0]+l1,c[0][1]+l3],[c[1][0]+l0,c[1][1]+l2],[c[1][0]+l0+l0,c[1][1]+l2+l2],[c[0][0]+l1+l1,c[0][1]+l3+l3]])
d.append([[c[0][0]+l1+l1,c[0][1]+l3+l3],[c[1][0]+l0+l0,c[1][1]+l2+l2], [c[2][0],c[2][1]],[c[3][0],c[3][1]]])
print(d)    #获得横向分成3等分的区域


if len(c) < 3:
    print('请重新运行,并点击3个以上坐标……')
else:
    h, w = img.shape[:2]  # #显示获取读取进来的图片长宽
    mask = np.zeros((h, w), dtype=np.uint8)  # 创建一个等图像大小的全黑背景
    fill_img2 = mask
    for i in range(0,3):
        ndarray_pts = np.array(d[i], np.int32)  # 将坐标数组转化成矩阵
        fill_img = cv2.fillPoly(mask, [ndarray_pts], color=i+1)  # 对所在区域进行填充颜色,参数二为上面获得的坐标矩阵, 参数3为填充颜色
        fill_img = fill_img[:, :, np.newaxis]  # np.newaxis用于增加第三维的维度
        fill_img = np.array(fill_img * [50, 100, 150]//3, np.uint8)  # 转化3维矩阵
        fill_img2 = cv2.add(img2, fill_img)  # 将两个图片像素相加
    cv2.imshow("image2", fill_img2)
    cv2.imwrite('1.jpg', fill_img2)
    cv2.waitKey(0)

 当然我们在运行的时候很可能会遇到opencv报错的问题

cv2.error: OpenCV(4.5.3) C:\\Users\\runneradmin\\AppData\\Local\\Temp\\pip-req-build-z4706ql7\\opencv\\modules\\highgui\\src\\window.cpp:1274: error: (-2:Unspecified error) The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Cocoa support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in function 'cvShowImage'
 

pip uninstall opencv-python
pip3 install opencv-contrib-python

当然报错还有可能是路径带有中文或空格有时也会报错。

还有的保存是函数的版本不同,老版本返回的是三个参数,新版本却只有两个参数

比如

contours,heriachy = cv.findContours(binary,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE)

那么本期博客就写到这里,

记得点赞关注加收藏,多支持博主,才能有动力日更不断!!!

有需要写代码 和修改代码的可以联系我的扣扣:334542894

以上是关于opencv-python通过鼠标点击图片获取该点坐标2,划分多个区域的主要内容,如果未能解决你的问题,请参考以下文章

安卓 百度地图API怎么点击地图获取坐标

请问Unity鼠标点击后如何获得当前所点击到的UI名字?

c#如何获取鼠标选取的内容

怎么用vue实现点击图片(按钮)的波纹效果(涟漪动效)

在MATLAB二维图中,随鼠标移动,显示该点的坐标信息,如何做到?谢谢大家,在线等

js获取鼠标点击事件的相对位置