记录123123

import cv2
import numpy as np
import os


img_path = "1.JPG"  # 图像路径
img_color = cv2.imread(img_path)  # 读取彩色图像
img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)  # 读取图像灰度图

t = img_path.split(".")[0]  # 获取到图像的名称,用来给文件夹命名
dir_name = "pic" + str(t)  # 文件夹名称
if not os.path.exists(dir_name):  # 判断文件夹pic是否存在,创建pic文件夹用来存放图像
    os.mkdir(dir_name)  # 如果不存在就创建文件夹

Gaussian_img = cv2.GaussianBlur(img, (3, 3), sigmaX=1)  # 高斯滤波
contour_list = []  # 定义一个列表,存放需要提取的轮廓,即筛选后的轮廓

for i in range(210, 250, 10):  
# 无法完全检测的原因是不同图像适用的阈值不同,因此增加对阈值的迭代
    ret, threshold = cv2.threshold(Gaussian_img, i, 255,
                                   cv2.THRESH_BINARY)  # 二值化,设置阈值为i,
    cv2.imwrite(dir_name + "/threshold.jpg", threshold)  # 保存图像

    kernel = np.ones((5, 5))  # 定义腐蚀的核
    img_erode = cv2.erode(threshold, kernel)  # 进行腐蚀操作  去栅格线  腐蚀:让白色变少,黑色变多,用于去毛刺
    cv2.imwrite(dir_name + "/img_erode.jpg", img_erode)  # 保存图像
    kernel2 = np.ones((15, 15))  # 定义膨胀的核
    img_dilate = cv2.dilate(img_erode, kernel2)  # 膨胀:让黑色变少,白色变多,用于让多个白块连接在一起,形成联通域
    cv2.imwrite(dir_name + "/img_dilate.jpg", img_dilate)  # 保存图像

    contours, hir = cv2.findContours(img_dilate, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)  # 对膨胀后的图像进行轮廓提取
    img_color_copy = img_color.copy()  # 复制彩色图像
    cv2.drawContours(img_color_copy, contours, -1, (0, 255, 0), 2)  # 绘制所有轮廓
    cv2.imwrite(dir_name + "/img_color_all_c.jpg", img_color_copy)  # 保存图像

    for c in contours:  # 对轮廓进行筛选
        area = cv2.contourArea(c)  # 求轮廓面积
        if 600000 < area < 1000000:  # 面积条件
            contour_list.append(c)  # 将满足条件的轮廓加入列表
        else:
            continue
    if len(contour_list) >= 22:  # 增加对轮廓个数的一个判断,如果达到了个数就结束迭代
        break

if len(contour_list) >= 22:  # 增加对轮廓个数的一个判断,如果达到了个数就继续操作,否则直接结束
    img_color_copy2 = img_color.copy()  # 复制彩色图像
    cv2.drawContours(img_color_copy2, contour_list, -1, (0, 0, 255), 2)  # 绘制筛选后的轮廓
    cv2.imwrite(dir_name + "/img_color_loc_c.jpg", img_color_copy2)  # 保存图像
    # 如下多行代码是使用近似轮廓对轮廓进行标号
    img_color_copy5 = img_color.copy()  # 复制彩色图像
    approx = []  # 近似轮廓的顶点坐标
    n = 1
    for c in contour_list:
        while True:
            a = 0.1  # a用来调整精度
            epsilon = a * cv2.arcLength(c, True)  # 近似轮廓的精度  参数为轮廓、是否闭合 精度越小越精确
            approx = cv2.approxPolyDP(c, epsilon, True)  # 近似轮廓  参数为轮廓、精度、否闭合  返回值为近似轮廓顶点坐标
            if len(approx) == 4:  # 判断顶点坐标个数,如果是四个,精度刚好合适,终止循环
                break
            elif len(approx) < 4:  # 如果小于四个,提高精度,进行迭代
                a -= 0.05
            else:  # 如果大于四个,减小精度,进行迭代
                a += 0.05
            if a <= 0:  # 如果a迭代为0或负值,终止迭代
                break
            elif a >= 0.3:  # 如果a迭代为0或负值,终止迭代
                break

        cv2.drawContours(img_color_copy5, [approx], -1, (0, 0, 255),
                         4)  # 将近似图像画出来  approx[0]左下,approx[1]右下,approx[2]右上,approx[3]左上(并不一定都会按照如此的顺序)
        # 这里存在一个bug。这个bug应该是cv2.approxPolyDP()函数自带的,四个顶点存在一定顺序,但是并不一定是从右上角开始的,这里需要特别注意,容易出bug!!
        # 且这个顺序在网上说是逆时针的,但实际应用的时候可以发现是顺时针的

        # 为了防止近似轮廓不是从右上角开始的bug,我们需要进行一个判断:
        if (approx[3][0][1] < approx[1][0][1]) & (
                approx[3][0][0] < approx[1][0][0]):  # 如果approx[3][0]为左上、approx[1][0]为右下
            center = approx[3][0][0] + int((approx[1][0][0] - approx[3][0][0]) / 2), approx[3][0][1] + int(
                (approx[1][0][1] - approx[3][0][1]) / 2)  # 确定近似轮廓的中心
            cv2.putText(img_color_copy5, str(n), center, cv2.FONT_HERSHEY_SIMPLEX, 5, (0, 0, 255), 2)  # 标号
            cv2.circle(img_color_copy5, center, 20, (0, 0, 255), -1)  # 画中心
            img_local = img_color_copy5[approx[3][0][1]:approx[1][0][1], approx[3][0][0]: approx[1][0][0]]  # 获取单个光伏板图像
            cv2.imwrite(dir_name + "/" + str(n) + ".jpg", img_local)

            src = np.float32([approx[0][0], approx[1][0], approx[2][0], approx[3][0]])  # 确定原图上的四个点,这里用近似轮廓的四个点
            dst = np.float32([[660, 0], [660, 1110], [0, 1110], [0, 0]])  # 确定仿射变换后对应的四个点
            M = cv2.getPerspectiveTransform(src, dst)  # 确定放射变换矩阵
            img_p = cv2.warpPerspective(img_color_copy5, M, (660, 1110))  # 进行透视变换
            cv2.imwrite(dir_name + "/" + str(n) + "-Perspective.jpg", img_p)

        elif (approx[3][0][1] > approx[1][0][1]) & (
                approx[3][0][0] > approx[1][0][0]):  # 如果approx[3][0]为右下、approx[1][0]为左上
            center = approx[1][0][0] + int((approx[3][0][0] - approx[1][0][0]) / 2), approx[1][0][1] + int(
                (approx[3][0][1] - approx[1][0][1]) / 2)  # 确定近似轮廓的中心
            cv2.putText(img_color_copy5, str(n), center, cv2.FONT_HERSHEY_SIMPLEX, 5, (0, 0, 255), 2)  # 标号
            cv2.circle(img_color_copy5, center, 20, (0, 0, 255), -1)  # 画中心
            img_local = img_color_copy5[approx[1][0][1]:approx[3][0][1], approx[1][0][0]: approx[3][0][0]]  # 获取单个光伏板图像
            cv2.imwrite(dir_name + "/" + str(n) + ".jpg", img_local)

            src = np.float32([approx[0][0], approx[1][0], approx[2][0], approx[3][0]])  # 确定原图上的四个点,这里用近似轮廓的四个点
            dst = np.float32([[0, 1110], [0, 0], [660, 0], [660, 1110]])  # 确定仿射变换后对应的四个点
            M = cv2.getPerspectiveTransform(src, dst)  # 确定放射变换矩阵
            img_p = cv2.warpPerspective(img_color_copy5, M, (660, 1110))  # 进行透视变换
            cv2.imwrite(dir_name + "/" + str(n) + "-Perspective.jpg", img_p)

        elif (approx[0][0][1] > approx[2][0][1]) & (
                approx[0][0][0] > approx[2][0][0]):  # 如果approx[0][0]为右下、approx[2][0]为左上
            center = approx[2][0][0] + int((approx[0][0][0] - approx[2][0][0]) / 2), approx[2][0][1] + int(
                (approx[0][0][1] - approx[2][0][1]) / 2)  # 确定近似轮廓的中心
            cv2.putText(img_color_copy5, str(n), center, cv2.FONT_HERSHEY_SIMPLEX, 5, (0, 0, 255), 2)  # 标号
            cv2.circle(img_color_copy5, center, 20, (0, 0, 255), -1)  # 画中心
            img_local = img_color_copy5[approx[2][0][1]:approx[0][0][1], approx[2][0][0]: approx[0][0][0]]  # 获取单个光伏板图像
            cv2.imwrite(dir_name + "/" + str(n) + ".jpg", img_local)

            src = np.float32([approx[0][0], approx[1][0], approx[2][0], approx[3][0]])  # 确定原图上的四个点,这里用近似轮廓的四个点
            dst = np.float32([[660, 1110], [0, 1110], [0, 0], [660, 0]])  # 确定仿射变换后对应的四个点
            M = cv2.getPerspectiveTransform(src, dst)  # 确定放射变换矩阵
            img_p = cv2.warpPerspective(img_color_copy5, M, (660, 1110))  # 进行透视变换
            cv2.imwrite(dir_name + "/" + str(n) + "-Perspective.jpg", img_p)

        elif (approx[2][0][1] > approx[0][0][1]) & (
                approx[2][0][0] > approx[0][0][0]):  # 如果approx[2][0]为右下、approx[0][0]为左上
            center = approx[0][0][0] + int((approx[2][0][0] - approx[0][0][0]) / 2), approx[0][0][1] + int(
                (approx[2][0][1] - approx[0][0][1]) / 2)  # 确定近似轮廓的中心
            cv2.putText(img_color_copy5, str(n), center, cv2.FONT_HERSHEY_SIMPLEX, 5, (0, 0, 255), 2)  # 标号
            cv2.circle(img_color_copy5, center, 20, (0, 0, 255), -1)  # 画中心
            img_local = img_color_copy5[approx[0][0][1]:approx[2][0][1], approx[0][0][0]: approx[2][0][0]]  # 获取单个光伏板图像
            cv2.imwrite(dir_name + "/" + str(n) + ".jpg", img_local)

            src = np.float32([approx[0][0], approx[1][0], approx[2][0], approx[3][0]])  # 确定原图上的四个点,这里用近似轮廓的四个点
            dst = np.float32([[0, 0], [660, 0], [660, 1110], [0, 1110]])  # 确定仿射变换后对应的四个点
            M = cv2.getPerspectiveTransform(src, dst)  # 确定放射变换矩阵
            img_p = cv2.warpPerspective(img_color_copy5, M, (660, 1110))  # 进行透视变换
            cv2.imwrite(dir_name + "/" + str(n) + "-Perspective.jpg", img_p)

        print(n)
        n += 1
        cv2.imwrite(dir_name + "/" + "img_color5_approx.jpg", img_color_copy5)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值