首页 > 解决方案 > 如何用矩阵位置标记图像上的数字?(按数字涂色)

问题描述

第一个过程我做了这个

import numpy as np
import cv2
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
import numpy as np
img = cv2.imread("img.jpg")
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) 
img = np.array(img, dtype=np.float64) / 255
plt.imshow(img)

然后我拿图像数据进行训练,通过 k-mean 找到平均颜色。

w, h, d = original_shape = tuple(img.shape)
print(w, h, d) # 627 783 3
img = np.reshape(img, (w * h, d))
img.shape # (490941, 3)
bit_of_color = 32
kmeans = KMeans(n_clusters=bit_of_color, random_state=0).fit(img)
labels = kmeans.predict(img)
kmeans.labels_ # array([16, 16, 16, ..., 28, 28, 28], dtype=int32)

之后,我创建了一个图像来显示从模型中获得的颜色。

image = np.zeros((w, h, d))
mean_ = kmeans.cluster_centers_
d = mean_.shape[1]
mean_[1]

def adjust_image(mean_color_from_model, labels, w, h):
    d = mean_color_from_model.shape[1]
    print(mean_color_from_model.shape)
    image = np.zeros((w, h, d))
    label_idx = 0
    for i in range(w):
        for j in range(h):
            image[i][j] = mean_color_from_model[labels[label_idx]] 
            # print(image[i][j])
            label_idx += 1
    print(label_idx)
    return image

plt.axis('off')
img_kmean = adjust_image(kmeans.cluster_centers_, labels, w, h)
plt.imshow(img_kmean)

并得到以下结果。 在此处输入图像描述

接下来,我将从图像中删除颜色,仍然是对象的唯一线条。

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('img2.png',0) 
edges = cv.Canny(img,100,200)
y, x = edges.shape
for i in range(y):
  for j in range(x):
    if (edges[i][j] == 0):
      edges[i][j] = 255
    elif (edges[i][j] == 255):
      edges[i][j] = 0
plt.imshow(edges,cmap = 'gray')
plt.show()

这是一个结果。 在此处输入图像描述

那么,如果我想使用矩阵的位置将数字标记到图像中怎么办?

期望的结果。(右图) 在此处输入图像描述

现在,我的流程如下。但这仍然是一个错误。如何让它变得更好? 在此处输入图像描述

遵守本准则

def check_bool(x, y, size_x, size_y):
    for j in range(y,y + size_y): 
      for k in range(x,x + size_x):  
        try:
          if (copy_edge[k][j] == 0): #255 W 0 B
            return False # ถ้าในกรอบเจอสีดำจะ set เป็น False และนำไป Plot ไม่ได้  
            break
        except:
            pass
    return True

def put_text(img_plt, text, x, y):
  cv2.putText(
              img_plt, #numpy array on which text is written
              str(text), #text
              (x,y), # x y
              cv2.FONT_HERSHEY_SIMPLEX, #font family
              0.5, #font size
              (0, 0, 0, 0), #font color
              2) #font stroke

size_x = 20
size_y = 20
copy_edge = edges.copy()
color_edge = img_kmean.copy()
y, x, d = color_edge.shape

for round in range(len(mean_color)):
  for y_ in range(0, y, size_y): 
    for x_ in range(0, x, size_x): 
      status = check_bool(x_, y_, size_x, size_y) # ถ้า Plot ได้
      # print(status)
      if status == True: # Putting text 
          c = sum(color_edge[y_][x_])
          c0 = sum(mean_color[round])
          if c == c0:
            put_text(copy_edge, round, x_, y_)
      
plt.figure(figsize = (17,10))
plt.imshow(copy_edge,cmap = 'gray')
plt.axis('off')

标签: pythonopencvimage-processinglabel

解决方案


要标记不为 0 的像素,您可以使用 opencv 的cv2connectedComponentsWithStats()函数

import numpy as np
import cv2 
from skimage.color import label2rgb 

# read the image as gray channel
I = cv2.imread("imgPath", 0)
# apply canny
edges = cv2.Canny(img,100,200)
# Invert the canny image
edges = 255 - edges

#dilating the mask to merge some edges(You can skip this step)
#edges = cv2.dilate(edges, np.ones((2,2)))
# label the bw mask from canny (white pixels are labelled automatically)
n, labels, _, _ = cv2.connectedComponentsWithStats(edges)
# convert the labels to RGB for visualization purpose
labels_rgb = np.uint8(255*label2rgb(labels, bg_label=0))
#save it
cv2.imwrite("./Pictures/bw.png", labels_rgb)

输入输出


推荐阅读