我试图检测比尔图像中的细胞:

I have this image enter image description here

删除了带有以下代码的戳记:

import cv2
import numpy as np

# read image
img = cv2.imread('dummy1.PNG')

# threshold on yellow
lower = (0, 200, 200)
upper = (100, 255, 255)
thresh = cv2.inRange(img, lower, upper)

# apply dilate morphology
kernel = np.ones((9, 9), np.uint8)
mask = cv2.morphologyEx(thresh, cv2.MORPH_DILATE, kernel)

# get largest contour
contours = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
big_contour = max(contours, key=cv2.contourArea)
x, y, w, h = cv2.boundingRect(big_contour)

# draw filled white contour on input
result = img.copy()
cv2.drawContours(result, [big_contour], 0, (255, 255, 255), -1)


cv2.imwrite('removed.png', result)

# show the images
cv2.imshow("RESULT", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

And obtained this image: enter image description here

然后应用灰度、反转、检测垂直和水平核,并通过该主 node 进行合并.py:

# Imports
import cv2
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import csv

try:
    from PIL import Image
except ImportError:
    import Image
import pytesseract

pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
#################################################################################################


# Read your file
file = 'removed.png'
img = cv2.imread(file, 0)
img.shape


# thresholding the image to a binary image
thresh, img_bin = cv2.threshold(img, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)

# inverting the image
img_bin = 255 - img_bin
cv2.imwrite(r'C:\Users\marou\Desktop\cv_inverted.png', img_bin)

# Plotting the image to see the output
plotting = plt.imshow(img_bin, cmap='gray')
plt.show()

# Define a kernel to detect rectangular boxes

# Length(width) of kernel as 100th of total width
kernel_len = np.array(img).shape[1] // 100
# Defining a vertical kernel to detect all vertical lines of image
ver_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, kernel_len))
# Defining a horizontal kernel to detect all horizontal lines of image
hor_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (kernel_len, 1))
# A kernel of 2x2
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))

#### Vertical LINES ####
# Use vertical kernel to detect and save the vertical lines in a jpg
image_1 = cv2.erode(img_bin, ver_kernel, iterations=5)
vertical_lines = cv2.dilate(image_1, ver_kernel, iterations=5)
cv2.imwrite(r'C:\Users\marou\Desktop\vertical.jpg', vertical_lines)
# Plot the generated image
plotting = plt.imshow(image_1, cmap='gray')
plt.show()

#### HORTIZONAL LINES ####
# Use horizontal kernel to detect and save the horizontal lines in a jpg
image_2 = cv2.erode(img_bin, hor_kernel, iterations=5)
horizontal_lines = cv2.dilate(image_2, hor_kernel, iterations=5)
cv2.imwrite(r'C:\Users\marou\Desktop\horizontal.jpg', horizontal_lines)
# Plot the generated image
plotting = plt.imshow(image_2, cmap='gray')
plt.show()



# Combining both H and V
# Combine horizontal and vertical lines in a new third image, with both having same weight.
img_vh = cv2.addWeighted(vertical_lines, 0.5, horizontal_lines, 0.5, 0.0)
# Eroding and thesholding the image
img_vh = cv2.erode(~img_vh, kernel, iterations=2)
thresh, img_vh = cv2.threshold(img_vh, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
cv2.imwrite(r'C:\Users\marou\Desktop\img_vh.jpg', img_vh)
plotting = plt.imshow(img_vh, cmap='gray')
plt.show()

To get this : enter image description here

现在,我正在努力填补由于水印删除而出现的空白,以便能够应用正确的OCR.

# Fill individual grid holes
cnts = cv2.findContours(result, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    x,y,w,h = cv2.boundingRect(c)
    cv2.rectangle(result, (x, y), (x + w, y + h), 255, -1)
cv2.imshow('result', result)
cv2.waitKey()

I get blank image: enter image description here

推荐答案

我概述了一种使用第二幅图像作为输入来填充表中缺失行的方法.

image = cv2.imread(image_path)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

enter image description here

现在为水平线创建一个单独的遮罩:

h_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (50,1))
# contains only the horizontal lines
h_mask = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, h_kernel, iterations=1)

# performing repeated iterations to join lines
h_mask = cv2.dilate(h_mask, h_kernel, iterations=7)

enter image description here

还有一个单独的垂直线遮罩:

v_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,50))
v_mask = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, v_kernel, iterations=1)

enter image description here

综合以上结果,我们得出以下结论:

joined_lines = cv2.bitwise_or(v_mask, h_mask)

enter image description here

上面的结果不是您所期望的,这些线已经超出了表的边界.为了避免这种情况,我创建了一个单独的遮罩来包围表格区域.

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
dilate = cv2.dilate(thresh, kernel, iterations=1)

enter image description here

现在,在上面的图像中找到最大的轮廓,并将其绘制在另一个二值图像上,以创建遮罩.

contours, hierarchy = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
c = max(contours, key = cv2.contourArea)           # contour with largest area
black = np.zeros((image.shape[0], image.shape[1]), np.uint8)
mask = cv2.drawContours(black, [c], 0, 255, -1)    # --> -1 to fill the contour

enter image description here

使用上面的图像作为遮罩覆盖在上面创建的连接线上

fin = cv2.bitwise_and(joined_lines, joined_lines, mask = mask)

enter image description here

100

可以在形态学操作上执行更多迭代,以更好地连接不连续线

Python相关问答推荐

如何计算部分聚合数据的统计数据

将numpy数组与空数组相加

sys.modulesgo 哪儿了?

"如果发生特定错误,返回值

如何防止Plotly在输出到PDF时减少行中的点数?

具有症状的分段函数:如何仅针对某些输入值定义函数?

使用pandas、matplotlib和Yearbox绘制时显示错误的年份

将HLS纳入媒体包

在函数内部使用eval(),将函数的输入作为字符串的一部分

三个给定的坐标可以是矩形的点吗

即使在可见的情况下也不相互作用

try 在树叶 map 上应用覆盖磁贴

Python+线程\TrocessPoolExecutor

Asyncio:如何从子进程中读取stdout?

如何从需要点击/切换的网页中提取表格?

幂集,其中每个元素可以是正或负""""

巨 Python :逆向猜谜游戏

通过追加列表以极向聚合

如何按row_id/row_number过滤数据帧

处理Gekko的非最优解