如何检测背景嘈杂的图像中的正方形

问题描述 投票:0回答:1

我有几张幼苗地块的图片。我想运行一个代码来切片每个方形罐并存储它。

为此,首先将其转换为灰度图像,然后减少噪声使其变蓝,最后使用阈值将其转换为二进制图像。

现在我正在尝试使用 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)

结果的问题是我得到的很多点并不完全是每个罐子的边界。 我非常感谢您的提示或帮助,我该如何优化它

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

python opencv image-processing
1个回答
0
投票

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

太好了,现在我们必须识别不同的方块。如果我们注意到,我们有一个由偶数正方形组成的 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')

其产量:

非常准确!现在我们还剩下一项任务:例如将每个苗区保存在名为

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 张裁剪图像的文件夹,如下所示,对应于第一行:

希望这有帮助!愿代码与您同在...

© www.soinside.com 2019 - 2024. All rights reserved.