【问题标题】:Python3 skimage - count number of picturesPython3 skimage - 计算图片数量
【发布时间】:2021-04-19 19:54:41
【问题描述】:

我有一张图片,我正在使用 skimage 来尝试检测:

  1. 页面中实际有多少图像 - 我希望它“计数”5

  2. 找到每张图片的角 - 所以如果它比我们的 maxCorners 数为 5,那么 maxCorners 应该是 5*4=20

  3. 在每个角之间绘制直线,并为 5 个图像中的每一个“蒙版”

现在我得到的只是正在读取的图像,填充孔洞,仅此而已 - 其他方面的指导?

from scipy import ndimage as nd
import imageio
from skimage import io, filters
from scipy import ndimage
import matplotlib.pyplot as plt

filename = "C:\\Users\\Tony\\Pictures\\img807.tif"

im = io.imread(filename, as_gray=True)
val = filters.threshold_otsu(im)
drops = ndimage.binary_fill_holes(im < val)
plt.imshow(drops, cmap='gray')
plt.show()

我试过查看这些资源:

具体是最后一个角点检测...

这是原始图像:

真实来源链接(12 小时):https://u.pcloud.link/publink/show?code=XZDONYXZVkUNFT2qcEFk4nFYYnx7d8swzaD7

【问题讨论】:

  • 用图片更新了主帖

标签: python-3.x image-processing computer-vision opencv3.0 scikit-image


【解决方案1】:

这个Answer是解决这个问题的关键。

坐标:

[[(38, 11), (251, 364)], [(254, 62), (592, 266)], [(254, 312),

(592, 518)], [(46, 456), (247, 797)], [(346, 557), (526, 797)]]

import numpy as np
import matplotlib.pyplot as plt
import cv2
import itertools

#====================================================
img = cv2.imread('input.jpg', 0)
blur = cv2.blur(img,(3,3))

blur[blur>225] = 0

sobelx = cv2.Sobel(blur,cv2.CV_64F,1,0,ksize=5)
sobely = cv2.Sobel(blur,cv2.CV_64F,0,1,ksize=5)
sobel = np.sqrt( sobelx**2 + sobely**2)

sobel = (255 * sobel)/(sobel.max() - sobel.min())
sobel = sobel.astype(np.uint8)
sobel[sobel<20] = 0
sobel[sobel>20] = 255
#====================================================

_,thresh = cv2.threshold(blur,127,255,1)
thresh = thresh + sobel

median = cv2.medianBlur(thresh,3)

gray_scale = median.copy()

image = np.stack([img, img, img], axis=2)

img_bin = cv2.Canny(gray_scale,50,110)
dil_kernel = np.ones((3,3), np.uint8)
img_bin=cv2.dilate(img_bin,dil_kernel,iterations=1)

line_min_width = 7

kernal_h = np.ones((2,line_min_width), np.uint8)
img_bin_h = cv2.morphologyEx(img_bin, cv2.MORPH_OPEN, kernal_h)

kernal_v = np.ones((line_min_width,1), np.uint8)
img_bin_v = cv2.morphologyEx(img_bin, cv2.MORPH_OPEN, kernal_v)

img_bin_final=img_bin_h|img_bin_v
final_kernel = np.ones((3,3), np.uint8)
img_bin_final=cv2.dilate(img_bin_final,final_kernel,iterations=1)

_, _, stats, _ = cv2.connectedComponentsWithStats(~img_bin_final, connectivity=8, ltype=cv2.CV_32S)

coords = []
### 1 and 0 and the background and residue connected components whihc we do not require
for x,y,w,h,area in stats[2:]:
    if area>15000:
        coords.append([(x,y),(x+w,y+h)])

def bb_intersection(coords, boxA, boxB):
    # determine the (x, y)-coordinates of the intersection rectangle
    xA = max(boxA[0][0], boxB[0][0])
    yA = max(boxA[0][1], boxB[0][1])
    xB = min(boxA[1][0], boxB[1][0])
    yB = min(boxA[1][1], boxB[1][1])
    # compute the area of intersection rectangle
    interArea = max(0, xB - xA + 1) * max(0, yB - yA + 1)
    # compute the area of both rectangles
    boxAArea = (boxA[1][0] - boxA[0][0] + 1) * (boxA[1][1] - boxA[0][1] + 1)
    boxBArea = (boxB[1][0] - boxB[0][0] + 1) * (boxB[1][1] - boxB[0][1] + 1)

    if(interArea == boxAArea):
        coords.remove(boxA)
    elif(interArea == boxBArea):
        coords.remove(boxB)
#
for boxa, boxb in itertools.combinations(coords, 2):
    bb_intersection(coords, boxa, boxb)

for coord in coords:
    cv2.rectangle(image,coord[0],coord[1],(0,255,0),1)

print(coords)

plt.imshow(image)
plt.title("There are {} images".format(len(coords)))
plt.axis('off')
plt.show()

编辑:

这个答案不是一个通用的解决方案,参数必须相应地调整,对于原始图像更改此块,代码将完美运行:

img = cv2.imread('input.tif', 0)

img = cv2.resize(img, (605, 830))

blur = img.copy()

blur[blur>225] = 0

sobelx = cv2.Sobel(blur,cv2.CV_64F,1,0,ksize=3)
sobely = cv2.Sobel(blur,cv2.CV_64F,0,1,ksize=3)
sobel = np.sqrt( sobelx**2 + sobely**2)

sobel = (255 * sobel)/(sobel.max() - sobel.min())
sobel = sobel.astype(np.uint8)
sobel[sobel<40] = 0
sobel[sobel>40] = 255

坐标:

[[(31, 16), (240, 364)], [(253, 56), (600, 265)], [(254, 309),

(605, 520)], [(40, 456), (248, 803)], [(347, 557), (534, 803)]]

【讨论】:

  • 奇怪 - 我只得到 2 张图像,它们周围没有边界框... [[(2316, 494), (5579, 2500)], [(3190, 5163), (4967, 7551 )]]
  • @Tony 我将这段代码与你提供的图像一起使用,我得到了这些结果,截图来自Matplotlib 的输出,你在这个image 上运行相同的代码吗?
  • 实际上不是,它不是真正的来源,但很好奇为什么它不适用于来源的表示,而不是实际的东西(更新的主帖,带有指向真实来源的链接)
  • @Tony 请查看更新后的答案,如果要将坐标映射到原始图像,则必须将坐标乘以调整大小。
  • 谢谢!现在确认它的工作 - 你怎么知道将数字调整到什么?即如果我切换图像?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-12
  • 1970-01-01
  • 1970-01-01
  • 2015-05-28
  • 1970-01-01
  • 1970-01-01
  • 2020-11-27
相关资源
最近更新 更多