Skip to content

day1

1.opencv识别书脊标签

import cv2
import numpy as np

# 读取图像
image = cv2.imread('IMG20240614164102.jpg')

# 确保图像已正确读取
if image is None:
    print("Error: Could not open or find the image")
    exit()

# 将图像从BGR转换到HSV
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

# 定义绿色的HSV范围
lower_green = np.array([35, 100, 100])
upper_green = np.array([77, 255, 255])

# 创建一个二值图像,其中只有绿色区域被标记为白色
mask = cv2.inRange(hsv, lower_green, upper_green)

# 使用位操作将原始图像中的非绿色区域设置为黑色
# 这里我们用掩码来提取绿色区域,并将其放置在一张全黑的背景上
result = cv2.bitwise_and(image, image, mask=mask)

# 为了确保背景完全是黑色,我们可以将非绿色区域设置为0
result[mask == 0] = [0, 0, 0]

# 显示原始图像和只包含绿色标签的图像
cv2.imshow('Original Image', image)
cv2.imshow('Image with only Green Labels', result)

# 等待用户按键,然后关闭窗口
cv2.waitKey(0)
cv2.destroyAllWindows()

img

71983200644

2.连接服务器

71981791537

71981951753

3.上传文件到GitHub

71993284713

71993289030

71993293843

day 2

1.opencv轮廓检测框出数字

import cv2
import os
import numpy as np


def crop_green_label_and_detect_numbers(image_folder):
    # 遍历图片文件夹

    for filename in os.listdir(image_folder):# 这个函数用于列出指定目录下的所有文件和目录名,但不包括子目录中的文件。
        #print(filename) #1.jpg  |  2.jpg
        if filename.lower().endswith(('.png', '.jpg', '.jpeg')):# 检查文件名是否以指定的图片格式结尾
            img_path = os.path.join(image_folder, filename)
            img = cv2.imread(img_path)
            if img is None:
                print(f"Error: Unable to read {img_path}")
                continue
            # os.path.join函数将image_folder和filename合并成一个完整的文件路径,并将结果存储在img_path变量中。




            # 转换到HSV色彩空间
            hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

            # 定义绿色的HSV范围
            lower_green = np.array([36, 25, 25])
            upper_green = np.array([70, 255, 255])

            # 创建一个掩模来分割绿色
            mask_green = cv2.inRange(hsv, lower_green, upper_green)

            # 找到掩模中的轮廓
            contours, _ = cv2.findContours(mask_green, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

            # 假设最大的轮廓是绿色标签(可能需要根据实际情况调整)
            if contours:
                max_contour = max(contours, key=cv2.contourArea)
                x, y, w, h = cv2.boundingRect(max_contour)
                # 裁剪绿色标签
                cropped_label = img[y:y + h, x:x + w]
                # cv2.imshow("2",cropped_label)

                # 对裁剪后的标签进行灰度转换和阈值化处理
                gray_label = cv2.cvtColor(cropped_label, cv2.COLOR_BGR2GRAY)
                # 二值化
                _, thresh_label = cv2.threshold(gray_label, 127, 255, cv2.THRESH_BINARY_INV)
                cv2.bitwise_not(thresh_label, thresh_label)
                # 开运算
                kernel = np.ones((3, 3), np.uint8)
                thresh_label = cv2.morphologyEx(thresh_label, cv2.MORPH_CLOSE, kernel)
                # 膨胀
                thresh_label = cv2.erode(thresh_label, kernel)
                # thresh_label = cv2.erode(thresh_label, kernel)
                cv2.imshow("sh", thresh_label)
                # 查找所有轮廓
                contours_numbers, _ = cv2.findContours(thresh_label, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
                cv2.imshow("sh", thresh_label)
                draw = cropped_label.copy()
                list1 = []
                # 循环轮廓
                for contours_number in contours_numbers:
                    x, y, w, h = cv2.boundingRect(contours_number)
                    S = w * h
                    #设定膨胀面积
                    if S < 100000 and S > 300:
                        list1.append(contours_number)
                res = cv2.drawContours(draw, list1, -1, (0, 0, 255), 2)
                cv2.imshow('res', draw)

                draw2 = cropped_label.copy()
                # 遍历轮廓并框出每个数字
                for cnt in list1:
                    x, y, w, h = cv2.boundingRect(cnt)
                    if w > 2 and h > 2:  # 根据数字的大小设置阈值
                        cv2.rectangle(draw2, (x, y), (x + w, y + h), (0, 0, 255), 2)  # 框出数字

                # 显示结果(可选:保存结果或进一步处理)
                cv2.imshow(f'1', draw2)
                cv2.waitKey(0)
                # cv2.destroyAllWindows()

    cv2.destroyAllWindows()


def crop_green_label_and_detect_numbers2(img_path):

            img = cv2.imread(img_path)

            # 转换到HSV色彩空间
            hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

            # 定义绿色的HSV范围
            lower_green = np.array([36, 25, 25])
            upper_green = np.array([70, 255, 255])

            # 创建一个掩模来分割绿色
            mask_green = cv2.inRange(hsv, lower_green, upper_green)

            # 找到掩模中的轮廓
            contours, _ = cv2.findContours(mask_green, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

            # 假设最大的轮廓是绿色标签(可能需要根据实际情况调整)
            if contours:
                max_contour = max(contours, key=cv2.contourArea)
                x, y, w, h = cv2.boundingRect(max_contour)
                # 裁剪绿色标签
                cropped_label = img[y:y + h, x:x + w]
                # cv2.imshow("2",cropped_label)

                # 对裁剪后的标签进行灰度转换和阈值化处理
                gray_label = cv2.cvtColor(cropped_label, cv2.COLOR_BGR2GRAY)
                # 二值化
                _, thresh_label = cv2.threshold(gray_label, 127, 255, cv2.THRESH_BINARY_INV)

                cv2.bitwise_not(thresh_label, thresh_label)
                # 开运算
                kernel = np.ones((3, 3), np.uint8)

                thresh_label = cv2.morphologyEx(thresh_label, cv2.MORPH_CLOSE, kernel)
                # 膨胀
                thresh_label = cv2.erode(thresh_label, kernel)
                # thresh_label = cv2.erode(thresh_label, kernel)
                cv2.imshow("sh", thresh_label)
                # 查找所有轮廓

                contours_numbers, _ = cv2.findContours(thresh_label, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
                cv2.imshow("sh", thresh_label)
                draw = cropped_label.copy()
                list1 = []
                # 循环轮廓
                for contours_number in contours_numbers:
                    x, y, w, h = cv2.boundingRect(contours_number)
                    S = w * h
                    #设定膨胀面积
                    if S < 100000 and S > 300:
                        list1.append(contours_number)
                res = cv2.drawContours(draw, list1, -1, (0, 0, 255), 2)
                cv2.imshow('res', draw)

                draw2 = cropped_label.copy()
                # 遍历轮廓并框出每个数字
                for cnt in list1:
                    x, y, w, h = cv2.boundingRect(cnt)
                    if w > 2 and h > 2:  # 根据数字的大小设置阈值
                        cv2.rectangle(draw2, (x, y), (x + w, y + h), (0, 0, 255), 2)  # 框出数字

                # 显示结果(可选:保存结果或进一步处理)
                cv2.imshow(f'1', draw2)
                cv2.imwrite("./tushu/photo.jpg",draw2)

                cv2.waitKey(0)
                cv2.destroyAllWindows()


if __name__=="__main__":
    # path=r"./tushu/3.jpg"
    # crop_green_label_and_detect_numbers2(path)
    # # 替换为你的图片文件夹路径
    image_folder = r'./tushu'
    crop_green_label_and_detect_numbers(image_folder)

71993327343

day 3

1.模板匹配

模板是被查找的图像。模板匹配是指查找模板在原始图像中的哪个位置的过程。

result = cv2.matchTemplate(image, templ, method, mask)

image: 原始图像

templ: 模板图像,尺寸必须小于或等于原始图像

method: 匹配的方法 mask:(可选)掩模,只有 cv2.TM_SQDIFF和 c2.TM_CCORR_NORMED 支持此参数,建议采用默认值 result: 计算得出的匹配结果。如果原始图像的宽、高分别为 W、H,模板图像的宽、高分别为 w、h,result 就是一个 W-w+1列、H-h+1行的32位浮点型数组。数组中每个浮点数都是原始图像中对应像素位置的匹配结果,其含义需要根据 method 参数来解读

retval是一个矩阵,大小为(N-M+1, M-N+1),其中N和M分别为大图像和小图像的高和宽。矩阵中的每个元素表示原始图像中与模板匹配度的一个指标,匹配越好,则值越大。

71997788090

单模板匹配

匹配过程中只用到一个模板的场景叫单模板匹配。原始图像中可能只有一个和模板相以的图像,也有可能有多个。如果只获取匹配程度最高的那一个结果,这种操作叫单目标配;如果需要同时获取所有匹配程度较高的结果,这种操作叫多目标匹配。

单目标匹配

单目标匹配只获取一个结果即可,就是匹配程度最高的结果 (如果使用平方差匹配,则为计算出的最小结果;如果使用相关匹配或相关系数匹配,则为计算出的最大结果)。本节以平方差匹配为例做介绍。

matchTemplate() 方法的计算结果是一个二维数组,minMaxLoc()方法专门用来解析这个二维数组中的最大值、最小值以及这两个值对应的坐标:

minValue, maxValue, minLoc, maxLoc = cv2.minMaxLoc(src, mask)

src: matchTemplate() 方法计算得出的数组 mask:(可选)掩模,建议使用默认值。 minValue: 数组中的最小值 maxValue: 数组中的最大值。 minLoc: 最小值的坐标,格式为(x,y)。 maxLoc: 最大值的坐标,格式为(x,y)。 平方差匹配的计算结果越小,匹配程度越高。minMaxLoc() 方法返回的 minValue 值是模板匹配的最优结果,minLoc 是最优结果区域左上角的点坐标,区域大小与模板大小一致。多目标匹配

多目标匹配

多目标匹配需要将原始图像中所有与模板相似的图像都找出来,使用相关匹配或相关系数匹配可以很好地实现这个功能。如果计算结果大于某一值,则认为匹配区域的图案和模板是相同的。

多模板匹配

匹配过程中同时查找多个模板的操作叫多模板匹配。多模板匹配实际上就是进行了n次“单模板多模板匹配”操作,n的数量为模板总数。

    # 替换为你的模板文件夹路径
    template_folder = r'D:\python\pythonProject2\tsg\mb'
    templates,templates_id = load_templates_from_folder(template_folder)

    #模板匹配的图片
    my_list=[]
    template_folder= r'D:\python\pythonProject2\tsg\cat'
    for filename in os.listdir(template_folder):
        # print("filename",filename )
        file_path = os.path.join(template_folder, filename)
        img=cv2.imread(file_path)
        gray_label2 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        matches = multi_template_match(gray_label2, templates,templates_id)
        my_list.append(matches[0])
    a="".join(my_list)
    print(a)
def crop_green_label_and_detect_numbers2(img_path):

    img = cv2.imread(img_path)

    # 转换到HSV色彩空间
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

    # 定义绿色的HSV范围
    lower_green = np.array([36, 25, 25])
    upper_green = np.array([70, 255, 255])

    # 创建一个掩模来分割绿色
    mask_green = cv2.inRange(hsv, lower_green, upper_green)

    # 找到掩模中的轮廓
    contours, _ = cv2.findContours(mask_green, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    # 假设最大的轮廓是绿色标签(可能需要根据实际情况调整)
    if contours:
        max_contour = max(contours, key=cv2.contourArea)
        x, y, w, h = cv2.boundingRect(max_contour)
        # 裁剪绿色标签
        cropped_label = img[y:y + h, x:x + w]
        # cv2.imshow("2",cropped_label)

        # 对裁剪后的标签进行灰度转换和阈值化处理
        gray_label = cv2.cvtColor(cropped_label, cv2.COLOR_BGR2GRAY)
        # 二值化
        _, thresh_label = cv2.threshold(gray_label, 127, 255, cv2.THRESH_BINARY_INV)

        cv2.bitwise_not(thresh_label, thresh_label)
        # 开运算
        kernel = np.ones((3, 3), np.uint8)

        thresh_label = cv2.morphologyEx(thresh_label, cv2.MORPH_CLOSE, kernel)
        # 膨胀
        thresh_label = cv2.erode(thresh_label, kernel)
        # thresh_label = cv2.erode(thresh_label, kernel)
        cv2.imshow("sh", thresh_label)
        # 查找所有轮廓

        contours_numbers, _ = cv2.findContours(thresh_label, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
        cv2.imshow("sh", thresh_label)
        draw = cropped_label.copy()
        list1 = []
        # 循环轮廓
        for contours_number in contours_numbers:
            x, y, w, h = cv2.boundingRect(contours_number)
            S = w * h
            #设定膨胀面积
            if S < 100000 and S > 300:
                list1.append(contours_number)
        res = cv2.drawContours(draw, list1, -1, (0, 0, 255), 2)
        cv2.imshow('res', draw)

        draw2 = cropped_label.copy()


def load_templates_from_folder(template_folder):
    """从指定文件夹加载模板图像,并返回一个模板列表及其名称的字典"""
    templates = []
    templates_id=[]
    # print("list",os.listdir(template_folder))
    #循环读取mb文件内的文件
    for filename in os.listdir(template_folder):
        # print("file",filename)
        file_path = os.path.join(template_folder, filename)
        #循环读取小文件夹内的内容
        for filename in os.listdir(file_path):
            img_path = os.path.join(file_path, filename)
            # print("img",img_path)
            img = cv2.imread(img_path, 0)  # 读取为灰度图
            # 使用文件名(不带扩展名)作为字典的键
            key = os.path.splitext(filename)[0][0]
            # print("key",key)
            templates.append(img)
            templates_id.append(key)
    # print(templates)
    return templates,templates_id

def multi_template_match(img, templates,templates_id):
    """在输入图像中执行多模板匹配,并返回匹配结果"""
    results = []
    for templ, name in zip(templates,templates_id):
        # w, h = templ.shape[::-1]
        res = cv2.matchTemplate(img, templ, cv2.TM_CCOEFF_NORMED)
        # print("res",res)
        threshold = 0.8  # 匹配阈值

        loc = np.where(res >= threshold)
        for i in zip(*loc[::-1]):
            results.append(name)# 使用文件名作为结果的键

    # print("result",results )
    return results

if __name__=="__main__":
    one()

72002165133

72002174056