【问题标题】:How to identify the complete grid in the image using Python OpenCV如何使用 Python OpenCV 识别图像中的完整网格
【发布时间】:2020-05-09 03:14:37
【问题描述】:

我目前正在处理一项图像处理任务,我需要识别网格单元并创建补丁,每个补丁作为单元格的网格。我可以使用图像下方的代码生成以下输出。

import numpy as np
import pandas as pd
import time 
from datetime import datetime
# from PIL import Image 
import torch 
import os, sys
import math
import cv2


# In[11]:


image = cv2.imread('../data/classes2.jpg')
print('rgb img shape : ',image.shape)
mask = np.zeros(image.shape, dtype=np.uint8)
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
print('gray img shape : ',gray.shape)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]




# In[15]:


# Detect only grid
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# print(cnts)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    area = cv2.contourArea(c)
    print(area)
    if area > 10000:
        cv2.drawContours(mask, [c], -1, (255,255,255), -1)


# In[16]:


mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
mask = cv2.bitwise_and(mask, thresh)


# In[17]:


# Find horizontal lines
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (55,1))
detect_horizontal = cv2.morphologyEx(mask, cv2.MORPH_OPEN, horizontal_kernel, iterations=2)
cnts = cv2.findContours(detect_horizontal, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    cv2.drawContours(image, [c], -1, (0,0,255), 2)


# In[18]:


# Find vertical lines
vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,25))
detect_vertical = cv2.morphologyEx(mask, cv2.MORPH_OPEN, vertical_kernel, iterations=2)
cnts = cv2.findContours(detect_vertical, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    cv2.drawContours(image, [c], -1, (0,0,255), 2)


# In[19]:


cv2.imshow('thresh', thresh)
cv2.imshow('mask', mask)
cv2.imshow('image', image)
cv2.waitKey()

但是,我无法完全识别轮廓中的网格线。我什至尝试锐化图像,但仍然没有成功。我是图像处理的新手。原图为:

编辑

一个补丁 = 一个网格单元 IE。网格的一个黄色单元格或橙色或白色单元格。我的目的是通过轮廓识别网格,然后逐个单元格裁剪网格单元格,其中每个方形单元格将充当补丁,然后我需要识别补丁/单元格的颜色。在这里,每个补丁都将保存为图像。

我已经修改了代码,但仍然缺少一些单元格。有没有更好的方法来识别单元格并将它们裁剪为补丁并识别它们的颜色,而不是首先识别网格。目前,我得到以下输出:

对于上述输出,我参考了以下代码:link to grid identification in image python code

尝试使用硬编码,我得到了重叠的补丁。以下代码是我尝试过的:

image = cv2.imread(image_path + 'classes2.jpg')
#claculate patch pixels
white_x_pixels = 5
white_y_pixels = 5
grid_rows, grid_cols = 50,51
patch_row_pixels = round((image.shape[0])/50,2)
patch_col_pixels = round((image.shape[1])/51,2)
print('patch_row_pixels : ',patch_row_pixels)
print('patch_col_pixels : ',patch_col_pixels)
w = ceil(patch_col_pixels) 
h = floor(patch_row_pixels) 
print('w:{},h:{}'.format(w,h))
image_number = 0
coord_dict = {}
for r in range(grid_rows):#(49,50):#(grid_rows): 
#     y = white_y_pixels + r*(h)
    if r in [0,1,2]:
        y = white_y_pixels + r*(h) 
    else : 
        y = r*(h) - 1
    yh = int(y+h) - white_y_pixels
    y = int(y)
    for c in range(grid_cols):#(49,51):#(grid_cols):#(1):#(grid_cols):
        coord_dict[image_number] = {}
        if c in [0,1,2]:
            x = white_x_pixels + c*(w)# - white_x_pixels)#patch_col_pixels
        else: 
            x = c*(w) - (white_x_pixels - 1)
        xw = int(x+w) - white_x_pixels
        x = int(x)
        ROI = image[y:yh,x:xw]
        coord_dict[image_number]['x'] = x
        coord_dict[image_number]['x+w'] = x+w
        coord_dict[image_number]['y'] = y
        coord_dict[image_number]['y+h'] = y+h
        coord_dict[image_number]['w'] = w
        coord_dict[image_number]['h'] = h
        print(x,xw,y,yh)
        cv2.imwrite('ROI_'+str(image_number) + '.png',ROI)
#         cv2.imshow('ROI_'+str(image_number),ROI)
#         cv2.waitKey(0)
#         cv2.destroyAllWindows()
        image_number += 1 

【问题讨论】:

  • 你的问题一点都不清楚。您能否详细说明补丁的含义以及您希望最终输出的方式。
  • @VardanAgarwal:你现在能看到问题吗,我已经编辑过了!如果您仍然不清楚,请告诉我。
  • 感谢问题现在很清楚。您能否澄清一下,网格单元或补丁总是与您显示的图像中的大小相同,因为这样问题很容易被硬编码。或者即使您可以使用图像处理获得一个补丁的大小,那么您只需运行嵌套循环并一次提取一个大小。即使您不明白我的意思,请澄清补丁是否相同大小,然后我会为其编写代码。
  • @VardanAgarwal : 所有补丁的大小都相同
  • @VardanAgarwal :我根据您解释的逻辑得到了重叠的补丁。你能帮我解释一下你告诉我的固定尺寸补丁的逻辑吗?我已经用代码更新了帖子?

标签: python opencv image-processing grid


【解决方案1】:

抱歉,之后我没有跟进。我尝试对您提供的图像进行硬编码,但它略微向右倾斜并且没有正确裁剪(我懒得数它们)。但为了展示如何做到这一点,我裁剪了图像的一小部分。

您可以使用原始图像尝试此代码。但是,您需要正确裁剪它并纠正该偏斜。

import cv2

img = cv2.imread('patches.jpg')
no_w = 7 # replace with no. of patches in width
no_h = 5 # replace with no. of patches in height
h, w = img.shape[:2]
pixels_w = round(w/no_w)
pixels_h = round(h/no_h)

for i in range(0, h, pixels_h):
    cv2.line(img, (0, i), (w, i), (0, 255, 0), 1)
for i in range(0, w, pixels_w):
    cv2.line(img, (i, 0), (i, h), (0, 255, 0), 1)

cv2.imshow('image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

结果

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-23
    • 2020-12-08
    • 2020-06-11
    • 2017-11-01
    • 2020-12-01
    • 2020-03-17
    • 2012-07-06
    • 2022-01-01
    相关资源
    最近更新 更多