代码【自用暂存】

代码【自用暂存】

import os

from PIL import Image
import cv2
import cv2 as cv
import numpy as np
from nsingle_numeracy_2 import zhizhen
from matplotlib import pyplot as plt
'''#图像预处理'''
import numpy as np
import cv2
def tiqu(HSV_img,circles,n ):
    low_hsv = np.array([150, 43, 46])
    high_hsv = np.array([180, 255, 255])
    # 使用opencv的inRange函数提取颜色
    mask_Red1 = cv2.inRange(HSV_img, lowerb=low_hsv, upperb=high_hsv)
    # Red = cv2.bitwise_and(target, target, mask=mask)
    # cv2.imshow("Red1", mask_Red1)
    # cv2.waitKey(0)
    low_hsv = np.array([0, 43, 46])
    high_hsv = np.array([10, 255, 255])
    # 使用opencv的inRange函数提取颜色
    mask_Red2 = cv2.inRange(HSV_img, lowerb=low_hsv, upperb=high_hsv)
    # cv2.imshow("Red2", mask_Red2)
    # cv2.waitKey(0)

    # Black = cv2.bitwise_and(target, target, mask=mask)
    maskRed = mask_Red1 + mask_Red2
    maskRed = cv2.medianBlur(maskRed, 11)  # 进行中值模糊,去噪点
    # 腐蚀膨胀
    # maskRed = cv2.erode(maskRed, None, iterations=2)
    # maskRed = cv2.dilate(maskRed, None, iterations=1)
    # # 获取尺寸
    # h, w, _ = img.shape
    # # 建立一个与图像尺寸相同的全零数组
    # npim = np.zeros((h, w, 3), dtype=np.int)
    # # 将图像3个通道相加赋值给空数组
    # npim[:] = img[:, :, 0] + img[:, :, 1] + img[:, :, 2]
    # 统计白色像素个数
    # print("白色像素点:", len(maskRed[maskRed == 255]))
    # if len(maskRed[maskRed == 255]) < 400:
    #     # # 统计黑色像素个数
    #     #
    #     # print(“黑色像素 % s个” % len(npim[npim == 0]))
    #     maskRed = cv2.erode(maskRed, None, iterations=2)
    #     maskRed = cv2.dilate(maskRed, None, iterations=1)
    # else:
    maskRed = cv2.erode(maskRed, None, iterations=n)
    maskRed = cv2.dilate(maskRed, None, iterations=1)


    cv2.imshow("thresh", maskRed)
    cv2.waitKey(0)

    cannyimage = cv2.Canny(maskRed, 50, 100)  # 边缘检测#调用Canny函数,指定最大和最小阈值,其中apertureSize默认为3。
    cv2.imshow("Red", maskRed)
    cv2.imshow("cannyimage", cannyimage)
    cv2.waitKey(0)
    circles = cv2.HoughCircles(cannyimage, cv2.HOUGH_GRADIENT, 1, 300, param1=100, param2=10, minRadius=10,
                               maxRadius=100)
    n=n-1
    return maskRed,circles,n,cannyimage
def tiqublack(img,circles,n ):
    # 使用opencv的inRange函数提取颜色
    low_hsv = np.array([0, 0, 0])
    high_hsv = np.array([180, 255, 46])
    # 使用opencv的inRange函数提取颜色
    mask_Black = cv2.inRange(img, lowerb=low_hsv, upperb=high_hsv)
    mask = cv2.medianBlur(mask_Black, 9)  # 进行中值模糊,去噪点
    # 腐蚀膨胀
    mask = cv2.erode(mask, None, iterations=n)
    mask = cv2.dilate(mask, None, iterations=1)
    cv2.imshow("thresh", mask)
    cv2.waitKey(0)

    cannyimage = cv2.Canny(mask, 50, 100)  # 边缘检测#调用Canny函数,指定最大和最小阈值,其中apertureSize默认为3# cv2.imshow("Black", mask_Black)
    circles = cv2.HoughCircles(cannyimage, cv2.HOUGH_GRADIENT, 1, 300, param1=100, param2=10, minRadius=3,
                               maxRadius=100)
    n=n+1
    return mask,circles,n,cannyimage
def gray_cvt(inputimagepath, graywindowname, outimagepath):
    gray_cvt_image = cv2.cvtColor(inputimagepath, cv2.COLOR_RGB2GRAY)  # 灰度化
    cv2.namedWindow(graywindowname)  # 控制显示图片窗口的名字
    cv2.imshow(graywindowname, gray_cvt_image)  # 显示灰度化后的图像
    cv2.imwrite(outimagepath, gray_cvt_image)  # 保存当前灰度值处理过后的文件
    # cv2.waitKey()  # 等待操作
    # cv2.destroyAllWindows()  # 关闭显示图像的窗口
def  dushu(x1,y1,x2,y2):
    if x1 == x2:
        return 90
    if y1 == y2:
        return 180
    k = -(y2 - y1) / (x2 - x1)
    # 求反正切,再将得到的弧度转换为度
    result = np.arctan(k) * 57.29577
    # 234象限
    if x1 > x2 and y1 > y2:
        result += 180
    elif x1 > x2 and y1 < y2:
        result += 180
    elif x1 < x2 and y1 < y2:
        result += 360
    if  54<result<=90 :
        n=0
    elif 18<result<=54 :
        n = 1
    elif 0<=result<=18  or 360>=result>342:
        n = 2
    elif 306<result<=342 :
        n = 3
    elif 270<result<=306 :
        n = 4
    elif 234<result<=270 :
        n = 5
    elif 198<result<=234 :
        n = 6
    elif 162<result<=198 :
        n = 7
    elif 126<result<=162 :
        n = 8
    elif 90<result<=126:
        n = 9
    else:
        print("读数发生错误!")
    print("直线倾斜角度为:" + str(result) + "度,读数为", n)  # 得到倾斜角度
    return int( n),result

def zhizhen(img,color):
        global cons_img
        graywindowname = 'gray_cvt'
        outimagepath = "gray_cvt.jpg"
        gray_cvt(img, graywindowname, outimagepath)#自带函数进行灰度化
        img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

        if color == 'b':
            # 提取黑色指针
            circles = None
            k =2
            while circles is None:
                mask, circles, k, cannyimage = tiqublack(img, circles, k)
                if circles is not None:
                    break
        if color == 'r':

            # 提取红色指针
            circles = None
            k =7
            while circles is None:
                mask, circles,k,cannyimage = tiqu(img, circles, k)
                if circles is not  None :
                    break

            # 根据检测到圆的信息,画出每一个圆
            maskpointpath = "maskpoint,jpg"
        cv2.imshow("cannyimage", cannyimage)
        cv2.waitKey(0)
        #检测指针圆心
        #circles = cv2.HoughCircles(mask_Black, cv2.HOUGH_GRADIENT, 1, 100, param1=100, param2=1, minRadius=10, maxRadius=15)
        ##原代码circles = cv2.HoughCircles(cannyimage, cv2.HOUGH_GRADIENT, 1, 300, param1=100, param2=2, minRadius=10, maxRadius=100)

        # 根据检测到圆的信息,画出每一个圆
        circles = np.uint16(np.around(circles))
        for i in circles[0, :]:
            # draw the outer circle
            cv2.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 2)
            # draw the center of the circle
            cv2.circle(img, (i[0], i[1]), 1, (0, 0, 255), 3)
            cv2.imshow('circle', img)


        # print(len(circles[0, :]))
        # # Shi-Tomasi 算法是Harris 算法的改进,角点算法识别指针顶端
        cons = []
        #corners = cv2.goodFeaturesToTrack(image, maxCorners, qualityLevel, minDistance, mask, blockSize, gradientSize[,corners[, useHarrisDetector[, k]]])
        con = cv2.goodFeaturesToTrack(mask ,1, 0.9, 10)
        if con is not None and len(con) > 0:
            for x, y in np.float32(con).reshape(-1, 2):
                cons.append((x, y))
                cons_img = cv2.circle(img, (int(x), int(y)), 1, (0, 0, 255))

        # 输出角点
        print(cons, i[0], i[1])
        cv2.imshow('cons_img ', cons_img)
        cv2.waitKey(0)

        linepic = cv2.line(img, (int(cons[0][0]), int(cons[0][1])), (int(i[0]), int(i[1])), (0, 0, 255))
        # if i[0] is int:
        n, ang = dushu(i[0], i[1], cons[0][0], cons[0][1])
        # print(n)
        # else:
        #     n, ang = dushu(int(i[0]),int( i[1]), int(cons[0][0]), int(cons[0][1]))

        #linepic = cv2.line(img, (cons[0][0], cons[0][1]), (i[0], i[1]), (0, 0, 255))


        cv2.imshow('linepic', linepic)
        cv2.waitKey(0)
        return (n)


# 圆形头像
# def circle(img_path):
#     # path_name = os.path.dirname(img_path)
#     # cir_file_name = 'cir_img.png'
#     # cir_path = path_name + '/' + cir_file_name
#     print("mask来了")
#     ima = Image.open(img_path).convert("RGBA")
#     size = ima.size
#     print(size)
#     # 因为是要圆形,所以需要正方形的图片
#     r2 = min(size[0], size[1])
#     if size[0] != size[1]:
#         ima = ima.resize((r2, r2), Image.ANTIALIAS)
#     # 最后生成圆的半径
#     r3 = int(r2 / 2)
#     imb = Image.new('RGBA', (r3 * 2, r3 * 2), (255, 255, 255, 0))
#     pima = ima.load()  # 像素的访问对象
#     pimb = imb.load()
#     r = float(r2 / 2)  # 圆心横坐标
#
#     for i in range(r2):
#         for j in range(r2):
#             lx = abs(i - r)  # 到圆心距离的横坐标
#             ly = abs(j - r)  # 到圆心距离的纵坐标
#             l = (pow(lx, 2) + pow(ly, 2)) ** 0.5  # 三角函数 半径
#             if l < r3:
#                 pimb[i - (r - r3), j - (r - r3)] = pima[i, j]
#     imb.save("1mask.jpg")





def dividing(img):
    src = img # 读取图片
    ROI = np.zeros(src.shape, np.uint8)   # 创建与原图同尺寸的空numpy数组,用来保存ROI信息
    gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)  # 灰度化
    #ret, binary = cv.threshold(gray,0, 255, cv.THRESH_BINARY_INV | cv.THRESH_TRIANGLE)  # 自适应二值化
    binary= cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY,19,10)
    #binary= cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,19,19)
    cv2.imshow("RO",  binary )
    cv2.waitKey(0)
    #circles = cv2.HoughCircles(binary, cv2.HOUGH_GRADIENT, 1, 50, param1=100, param2=21, minRadius=20, maxRadius=40)
    circles = cv2.HoughCircles(binary, cv2.HOUGH_GRADIENT, 1, 50, param1=100, param2=21, minRadius=20, maxRadius=40)
    # 根据检测到圆的信息,画出每一个圆
    circles = np.uint16(np.around(circles))
    n=0
    x = [[] for i in range(8)]
    for i in circles[0, :]:
      if n<8:
        x[n].append(i[0])
        x[n].append(i[1])
        x[n].append(i[2])#存储圆的信息
        n = n + 1
      else :
        break
    #     # draw the outer circle
    #     cv2.circle(src, (i[0], i[1]), i[2]+1, (0, 255, 0), 2)
    #     # draw the center of the circle
    #     cv2.circle(src, (i[0], i[1]), 1, (0, 0, 255), 3)
    # cv2.imshow('circle', src)
    # cv2.waitKey(0)
    # print(x)
    x=np.array(x)
    x=x[x[:,0].argsort()]#根据图上位置排序表盘
    # print('new',x)
    n=0
    ang = [0, 0, 0, 0, 0, 0, 0, 0]
    for i in range(len(x)):
        # draw the outer circle
        circle = np.zeros(ROI.shape[0:2], dtype="uint8")  # 创建圆
        maskcircle = cv2.circle(circle,(x[i][0], x[i][1]), x[i][2],255, -1)  # 修改填充白色
        #
        # 添加白色背景
        mask = np.zeros(ROI.shape[0:2], dtype="uint8")  # 创建矩形
        mask =cv2.rectangle(mask, (x[i][0]- x[i][2]-1, x[i][1]- x[i][2]-1), (x[i][0]+x[i][2]+1, x[i][1]+ x[i][2]+1),255, -1)
        mask = cv2.add(src, np.zeros(np.shape(src), dtype=np.uint8), mask=mask)
        # cv2.imshow('result.jpg', mask)
        # cv2.waitKey(0)
        bg = np.ones_like(img, np.uint8) * 255

        cv2.bitwise_not(bg, bg, mask=maskcircle)  # bg的多边形区域为0,背景区域为255
        mask=mask+bg
        # rows, cols, channel = mask.shape
        # # 创建一张4通道的新图片,包含透明通道,初始化是透明的
        # img_new = np.zeros((rows, cols, 4), np.uint8)
        # img_new[:, :, 0:3] = mask[:, :, 0:3]
        # # 创建一张单通道的图片,设置最大内接圆为不透明,注意圆心的坐标设置,cols是x坐标,rows是y坐标
        # img_circle = np.zeros((rows, cols, 1), np.uint8)
        # img_circle[:, :, :] = 0  # 设置为全透明
        # img_circle = cv2.circle(img_circle, (cols / 2, rows / 2), min(rows, cols) / 2, (255), -1)  # 设置最大内接圆为不透明
        # # 图片融合
        # mask[:, :, 3] = img_circle[:, :, 0]
        # # 保存图片
        # cv2.imwrite(mask + ".png", mask)
        # # cv2.imencode('.jpg', img)[1].tofile('./9.jpg')  # 保存到另外的位置


        # mask = src[x[i][1]- x[i][2]-1:x[i][1]+ x[i][2]+1, x[i][0]- x[i][2]-1:x[i][0]+x[i][2]+1 ]  # 裁剪矩形坐标为[y0:y1, x0:x1]
        # cv2.imwrite("1mask.jpg",mask)
        # circle("1mask.jpg")
        # mask =cv2.imread("1mask.jpg")
        # cv2.imwrite("1mask.jpg",mask)
        # # 从中心开始 剪切 200*200的图片mask
        # print( src.size[0], src.size[1])
        # half_the_width = src.size[0] / 2
        # half_the_height = src.size[1] / 2
        # mask = img.crop(
        #     (
        #         half_the_width - x[i][2]/2,
        #         half_the_height - x[i][2]/2,
        #         half_the_width + x[i][2]/2,
        #         half_the_height + x[i][2]/2
        #     )
        # )
        # mask = mask.crop((x[i][0], x[i][1], x[i][2], x[i][2]))
        cv2.imshow('result.jpg', mask)
        cv2.waitKey(0)


        # cv2.circle(ROI,(x[i][0], x[i][1]), x[i][2]+2, (255, 255, 255),-1)#注:必须为实心
        # imgroi = ROI & src
        # cv2.imshow("ROI", imgroi)
        # cv2.waitKey(0)
        # cv2.destroyAllWindows()

        # cv2.imwrite("ROI.jpg")
        if n>=0and n<=3 :
            ang[n]=zhizhen(mask,'b')

        elif 3<n<8:
            ang[n]=zhizhen(mask,'r')

        n=n+1
    print("黑色指针部分水表读数为:", ang[2], ang[0], ang[1], ang[3])
    print("红色指针部分水表读数为:", ang[4], ang[6], ang[7], ang[5])
if __name__ == '__main__':
     #img = "train5.jpeg"
     img = "1second_template.jpg"
     #img = "train6.jpeg"
     #img = "train7.jpeg"
     img = cv2.imread(img)
#第一步:选出ROI区域,分割成单个圆盘
     dividing(img)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值