美文网首页
2022-06-14 Python OpenCV 常用工具类

2022-06-14 Python OpenCV 常用工具类

作者: 颈椎以上瘫痪 | 来源:发表于2022-06-14 10:00 被阅读0次

    显示图像

    cv.imshow()是显示图像的函数,需要2个参数,一个是需要显示的图像,还一个是显示图像窗口的标题,在一个进程中同样标题的窗口只能存在一个,比如你先显示一个标题1的图像,再显示一个标题1的图像,那么后显示的图像窗口就会将前面那个销毁掉。这个函数显示图像窗口是OpenCV的调试窗口,默认是不能缩放的,图像有多大,窗口就显示多大,但是在过程中我们往往会显示很多窗口,也需要手动缩放和拖动这些窗口,所以在定义这个窗口时需要执行一个cv.WINDOW_NORMAL属性,然后在这个窗口里面显示图像就可以缩放了。

    # 显示图像
    def show(title, image):
        cv.namedWindow(title, cv.WINDOW_NORMAL)
        cv.imshow(title, image)
    

    绘制矩形

    cv.rectangle()是在图像上绘制一个矩形的函数,需要的参数有一个图像,2个点(左上角和右下角),矩形框的颜色,矩形框的线宽。注意这里传入的坐标点的值不能是小数,如果你在计算过程中的数据精确到小数了,这里就需要采取一些手段来避免出错,比如这里对坐标值使用四舍五入。

    def drawRectangle(canvas, p1, p2):
        cv.rectangle(canvas, (round(p1[0]), round(p1[1])), (round(p2[0]), round(p2[1])), (0, 0, 255), 2)
    

    三角形已知三个角和1条边,求另2条边

    三角形已知3个角度值和1条边长,可以使用这个函数计算另2条边长,注意数据的顺序,边长按照顺序其对角的顺序。

    def calSide(angles, a):
        angleA = angles[0]
        angleB = angles[1]
        angleC = angles[2]
    
        b = math.sin(angleB / 180 * math.pi) * a
        c = math.cos(angleB / 180 * math.pi) * a
        return b, c
    

    获取图像中某区域附近红色和绿色像素分量

    def getRedAndGreenCount(img, point, offset, canvas):
        # 根据偏移量,在点附近绘制矩形
        cv.rectangle(canvas, (round(point[0] - offset), round(point[1] - offset)),
                     (round(point[0] + offset), round(point[1] + offset)), (0, 0, 255), 1)
    
        # 将这个矩形裁剪出来
        status = img[round(point[1] - offset):round(point[1] + offset), round(point[0] - offset):round(point[0] + offset)]
        if status is None:
            return None
        # show("RedAndGreen"+str(point),status)
        try:
            count = redAndGreen(status)
            return count
        except Exception:
            return None
        pass
    

    判断图像中红色和绿色像素分量的数量

    def redAndGreen(img):
        # 先将图像转成HSV
        hsvSrc = cv.cvtColor(img, cv.COLOR_BGR2HSV)
        # 找红色区间
        lowerColorRed = np.array([0, 43, 46])
        upperColorRed = np.array([10, 255, 255])
        hsvRed = cv.inRange(hsvSrc, lowerColorRed, upperColorRed)
        # 找绿色区间
        lowerColorGreen = np.array([35, 43, 46])
        upperColorGreen = np.array([77, 255, 255])
        hsvGreen = cv.inRange(hsvSrc, lowerColorGreen, upperColorGreen)
    
        # 找出各颜色图像中白色像素点的数量
        redCount = 0
        greenCount = 0
        w, h, c = img.shape
        for j in range(w):
            for k in range(h):
                if hsvRed[j, k] == (255.0):
                    redCount = redCount + 1
                if hsvGreen[j, k] == (255.0):
                    greenCount = greenCount + 1
    
        return greenCount + redCount
    

    判断图像是红色还是绿色

    def redOrGreen(img):
        # 先将图像转成HSV
        hsvSrc = cv.cvtColor(img, cv.COLOR_BGR2HSV)
        # 找红色区间
        lowerColorRed = np.array([0, 43, 46])
        upperColorRed = np.array([10, 255, 255])
        hsvRed = cv.inRange(hsvSrc, lowerColorRed, upperColorRed)
        # 找绿色区间
        lowerColorGreen = np.array([35, 43, 46])
        upperColorGreen = np.array([77, 255, 255])
        hsvGreen = cv.inRange(hsvSrc, lowerColorGreen, upperColorGreen)
    
        # 找出各颜色图像中白色像素点的数量
        redCount = 0
        greenCount = 0
        w, h, c = img.shape
        for j in range(w):
            for k in range(h):
                if hsvRed[j, k] == (255.0):
                    redCount = redCount + 1
                if hsvGreen[j, k] == (255.0):
                    greenCount = greenCount + 1
    
        if greenCount > redCount:
            return 1
        else:
            return 0
    

    计算线段中点1到点2的方向

    def calAngleLine(line):
        angle = 0
        point1 = (line[0], line[1])
        point2 = (line[2], line[3])
        x1, y1 = point1
        x2, y2 = point2
    
        # 水平
        if y1 == y2:
            # 右
            if x1 < x2:
                angle = 0
            # 左
            elif x1 > x2:
                angle = 180
            # 同一个点
            else:
                angle = 0
        # 向上
        elif y1 > y2:
            # 右上
            if x1 < x2:
                angle = 360 - calAngle(point1, point2, (x2, y1))[0]
            # 左上
            elif x1 > x2:
                angle = 180 + calAngle(point1, point2, (x2, y1))[0]
            # 上
            else:
                angle = 270
        # 向下
        else:
            # 右下
            if x1 < x2:
                angle = calAngle(point1, point2, (x2, y1))[0]
            # 左下
            elif x1 > x2:
                angle = 180 - calAngle(point1, point2, (x2, y1))[0]
            # 下
            else:
                angle = 90
        return angle
    

    已知3个点求其三角形的角度

    返回的数组中3个角度值,与传参进来的点的顺序是对应的。

    def calAngle(p1, p2, p3):
        angles = []
        a = math.sqrt((p2[0] - p3[0]) * (p2[0] - p3[0]) + (p2[1] - p3[1]) * (p2[1] - p3[1]))
        b = math.sqrt((p1[0] - p3[0]) * (p1[0] - p3[0]) + (p1[1] - p3[1]) * (p1[1] - p3[1]))
        c = math.sqrt((p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]))
        A = math.degrees(math.acos((a * a - b * b - c * c) / (-2 * b * c)))
        B = math.degrees(math.acos((b * b - a * a - c * c) / (-2 * a * c)))
        C = math.degrees(math.acos((c * c - a * a - b * b) / (-2 * a * b)))
        angles.append(A)
        angles.append(B)
        angles.append(C)
        return angles
    

    角度校正

    在使用角度时我们往往只需要0-360的值,但是角度在经过计算后经常会超过边界,所以使用这个函数可以将超出边界的值换算到边界内。

    def rectifyAngle(angle):
        if angle >= 360:
            angle = angle - 360
        elif angle < 0:
            angle = angle + 360
    
        if angle < 0 | angle >= 360:
            return rectifyAngle(angle)
    
        return angle
    

    计算点的偏移坐标

    计算一个点的偏移坐标,需要一个点、一个角度、一个距离,计算出偏移后的点。

    def calPoint4AngleDistance(center, angle, distance):
        x, y = center
        point = ()
        if angle >= 360:
            angle %= 360
        # 右
        if angle == 0:
            point = (x + distance, y)
            pass
        # 下
        elif angle == 90:
            point = (x, y + distance)
            pass
        # 左
        elif angle == 180:
            point = (x - distance, y)
            pass
        # 上
        elif angle == 270:
            point = (x, y - distance)
            pass
        # 右下
        elif angle > 0 and angle < 90:
            angles = []
            angles.append(90)
            angles.append(angle)
            angles.append(90 - angle)
            b, c = calSide(angles, distance)
            point = (x + c, y + b)
            pass
        # 左下
        elif angle > 90 and angle < 180:
            angles = []
            angles.append(90)
            angles.append(180 - angle)
            angles.append(angle - 90)
            b, c = calSide(angles, distance)
            point = (x - c, y + b)
            pass
        # 左上
        elif angle > 180 and angle < 270:
            angles = []
            angles.append(90)
            angles.append(angle - 180)
            angles.append(270 - angle)
            b, c = calSide(angles, distance)
            point = (x - c, y - b)
            pass
        # 右上
        elif angle > 270 and angle < 360:
            angles = []
            angles.append(90)
            angles.append(360 - angle)
            angles.append(angle - 270)
            b, c = calSide(angles, distance)
            point = (x + c, y - b)
            pass
    
        return point
    

    求两点间距离

    def getDistance(p1, p2):
        distance = math.pow((p1[0] - p1[0]), 2) + math.pow((p2[1] - p2[1]), 2)
        distance = math.sqrt(distance)
        return distance
    

    相关文章

      网友评论

          本文标题:2022-06-14 Python OpenCV 常用工具类

          本文链接:https://www.haomeiwen.com/subject/astzmrtx.html