我有几张苗圃的图片.我想运行一个代码来切割每个方形锅并存储它.

Original Image To do this, first convert it to gray image then to reduce noise bluer it and finally convert it to binary using threshold. thresh

现在我试图使用cv.findContours找到每个正方形的几何位置,但似乎只能返回图像角落中的点,而不是找到每个正方形的角落.

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (3, 3), 0)
edges = cv2.Canny(blurred, 10, 50)

thresh = cv2.adaptiveThreshold(gray, 400, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 7, 4)
lines = cv2.HoughLines(thresh, rho=1, theta=np.pi/180, threshold=100)
contours, hierarchy = cv2.findContours(edges, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE) 
squares = []
for contour in contours:
    peri = cv2.arcLength(contour, True)
    approx = cv2.approxPolyDP(contour, 0.02 * peri, True)
    if len(approx) == 4:
        x, y, w, h = cv2.boundingRect(approx)
        aspect_ratio = float(w) / h
        if 0.98 <= aspect_ratio <= 1:  # Adjust this range as per your requirement
            squares.append(approx)
# Draw squares on the original image
for square in squares:
    cv2.drawContours(image, [square], -1, (0, 255, 0), 2)

结果的问题是我得到的很多点并不完全是每个锅的边界. 我很感激您的建议或帮助,我如何优化它

result

我已经搜索过之前的帖子,但大多数都是在光线和对比度足够的情况下进行的,但在这种情况下不适用

推荐答案

我们可以在这里采取两种全球方法:自始至终使用计算机视觉(可能不准确),或者使用变通方法(更简单的方法).后者似乎更好.因此,首先,我们必须裁剪原始图像,以留下仅具有幼苗地块网格的图像.这可以使用任何简单的图像处理工具(即,在Mac上预览或在Windows上绘制):

Cropped seedling plots

很好,现在,我们必须识别不同的方块.如果我们注意到的话,我们有一个由偶数正方形组成的10x6网格,所以我们可以如下使用matplotlib:

import matplotlib.pyplot as plt
import matplotlib.patches as patches

def draw_seedling_squares(image_path, grid_size=(10, 6)):
    # Load the image
    img = plt.imread(image_path)
    
    # Create a new figure
    fig, ax = plt.subplots()
    ax.imshow(img)
    
    # Calculate the width and height of each square
    img_height, img_width, _ = img.shape
    square_width = img_width / grid_size[0]
    square_height = img_height / grid_size[1]
    
    # Draw squares above each seedling plot
    for i in range(grid_size[0]):
        for j in range(grid_size[1]):
            x = i * square_width
            y = j * square_height
            rect = patches.Rectangle((x, y), square_width, square_height, linewidth=1, edgecolor='r', facecolor='none')
            ax.add_patch(rect)
    
    # Show the image with squares
    plt.show()

draw_seedling_squares('cropped_image.jpeg')

这会产生:

grid of seedling plots

非常准确!现在我们还剩一项任务:例如,将每个幼苗地块保存在名为screenshots的文件夹中.为此,我们可以对上面的代码进行以下修改:

import os
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches

def extract_and_save_seedling_plots(image_path, output_folder='screenshots', grid_size=(10, 6)):
    # Create the output folder if it doesn't exist
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    
    # Load the image
    img = plt.imread(image_path)
    
    # Calculate the width and height of each seedling plot
    img_height, img_width, _ = img.shape
    plot_width = img_width / grid_size[0]
    plot_height = img_height / grid_size[1]
    
    # Extract and save each seedling plot as individual files
    for i in range(grid_size[0]):
        for j in range(grid_size[1]):
            x = i * plot_width
            y = j * plot_height
            
            # Define the bounding box for cropping
            bbox = (int(x), int(y), int(x + plot_width), int(y + plot_height))
            
            # Crop the seedling plot
            seedling_plot = img[bbox[1]:bbox[3], bbox[0]:bbox[2]]
            
            # Save the cropped seedling plot as an individual file
            filename = os.path.join(output_folder, f'seedling_plot_{i}_{j}.png')
            plt.imsave(filename, seedling_plot)

extract_and_save_seedling_plots('cropped_image.jpeg')

太好了!现在我们有了一个文件夹,其中包含60张裁剪图像,如下所示,对应于第一行:

p0 p1 p2 p3 p4 p5 p6 p7 p8 p9

希望这有帮助!愿密码与你同在……

Python相关问答推荐

实现的差异取决于计算出的表达是直接返回还是首先存储在变量中然后返回

LAB中的增强数组

如何在Python中使用io.BytesIO写入现有缓冲区?

Python 3.12中的通用[T]类方法隐式类型检索

Python中的嵌套Ruby哈希

不理解Value错误:在Python中使用迭代对象设置时必须具有相等的len键和值

如何让程序打印新段落上的每一行?

根据二元组列表在pandas中创建新列

修复mypy错误-赋值中的类型不兼容(表达式具有类型xxx,变量具有类型yyy)

将9个3x3矩阵按特定顺序排列成9x9矩阵

如何在Python中使用另一个数据框更改列值(列表)

Pandas:计算中间时间条目的总时间增量

ruamel.yaml dump:如何阻止map标量值被移动到一个新的缩进行?

pysnmp—lextudio使用next()和getCmd()生成器导致TypeError:tuple对象不是迭代器''

递归函数修饰器

freq = inject在pandas中做了什么?''它与freq = D有什么不同?''

Python—在嵌套列表中添加相同索引的元素,然后计算平均值

ModuleNotFoundError:Python中没有名为google的模块''

如何获得满足掩码条件的第一行的索引?

在pandas中,如何在由两列加上一个值列组成的枢轴期间或之后可靠地设置多级列的索引顺序,