朋友小明跟我提了一个现在遇到的问题,他们公司(天注定办公礼品智慧定制)是做定制化礼品的公司,在他家网上商城采购的东西,可以打上用户的特殊字符,比如我想买一个抱枕送给我媳妇,抱枕上可以打印上我媳妇的名字。(后来我真的买了一个抱枕给我媳妇,我媳妇很高兴,也奖励了我一个抱枕)
客户有时候要在礼品上打印公司的图标,如果打印在一个不锈钢材质的杯子上,是没有颜色的。这就需要程序员把图片变成黑白的,然后送给机器打印。小明说能否用算法自动生成这些黑白图像。另外他提出,现在人工智能这么火,是不是用人工智能技术,送入彩色图片,得到黑白图片,最终集成到网页上,用户输入彩色图片,网址后台直接给出黑白图标。客户的图片各种各样,简单的黑白化是不行的。
我的意见是现在的深度学习模型理论上是可以解决这个问题的,但是需要一些数据做监督学习,至少5000张吧,做起来也比较麻烦,且部署也是一个问题,至少服务器上得买一块10000元的显卡。现有的服务器可能装不上,估计得买一个新的服务器。
能否换一个思路,采用传统的视觉算法,输入彩色图片,然后传统算法给出10张不同二值化方法得到的黑白图片,让用户选一张。这种代码比较简单,我晚上给你代码你试试。
然后我把代码给小明,小明试了下感觉效果不错,过了几天上线了,运行了一个月后,小明反应客户在给出的10张备选图片中,几乎只选则特定的2张,后来把备选图片弄成2张了。
下面是各种二值化方法的代码。
# coding=utf-8
# USAGE
#
# import the necessary packages
import numpy as np
import cv2
import os
import time
import imutils
import argparse
# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", default='test.jpg',
help="path to the input image")
args = vars(ap.parse_args())
file_name = args["image"];
# read image
img_gray = cv2.imdecode(np.fromfile(file_name, dtype=np.uint8), 0)
# save some binary image by different threshold
for j in range(100,250, 5):
_, threshold_binary = cv2.threshold(img_gray, j, 255, cv2.THRESH_BINARY)
cv2.imencode(".jpg", threshold_binary)[1].tofile(file_name + "-sh-binary-" + str(j) + ".jpg")
# save coutours image
img_gray_contours = img_gray.copy()
img_gray_contours = 255 - img_gray_contours
cnts = cv2.findContours(img_gray_contours.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
cnts = imutils.grab_contours(cnts)
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)
img_gray_contours = img_gray_contours - img_gray_contours
cv2.drawContours(img_gray_contours, cnts, -1, (255), thickness=cv2.FILLED)
img_gray_contours = 255 - img_gray_contours
cv2.imencode(".jpg", img_gray_contours)[1].tofile(
file_name + "-sh-contour-" + str(0) + ".jpg")
# save adapt threshold image
mean_c = cv2.adaptiveThreshold(img_gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 15, 12)
cv2.imencode(".jpg", mean_c)[1].tofile(
file_name + "-sh-adathres-" + str(0) + ".jpg")
gaus = cv2.adaptiveThreshold(img_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 91, 12)
cv2.imencode(".jpg", gaus)[1].tofile(
file_name + "-sh-adathres-" + str(1) + ".jpg")
# save tophat image
kernel = np.ones((50, 50), np.uint8)
tophat = cv2.morphologyEx(img_gray, cv2.MORPH_TOPHAT, kernel)
cv2.imencode(".jpg", tophat)[1].tofile(
file_name + "-sh-tophat-" + str(0) + ".jpg")
# save blankhat image
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (50, 50))
blankhat = cv2.morphologyEx(img_gray, cv2.MORPH_BLACKHAT, kernel)
cv2.imencode(".jpg", blankhat)[1].tofile(
file_name + "-sh-blankhat-" + str(0) + ".jpg")
# read color image
img_color = cv2.imdecode(np.fromfile(file_name, dtype=np.uint8), 1)
# save single channel of rgb image
b, g, r = cv2.split(img_color)
cv2.imencode(".jpg", b)[1].tofile(
file_name + "-sh-b-" + str(0) + ".jpg")
cv2.imencode(".jpg", g)[1].tofile(
file_name + "-sh-g-" + str(0) + ".jpg")
cv2.imencode(".jpg", r)[1].tofile(
file_name + "-sh-r-" + str(0) + ".jpg")
hsv = cv2.cvtColor(img_color, cv2.COLOR_BGR2HSV)
# save single channel of hsv image
h, s, v = cv2.split(hsv)
cv2.imencode(".jpg", h)[1].tofile(
file_name + "-sh-h-" + str(0) + ".jpg")
cv2.imencode(".jpg", s)[1].tofile(
file_name + "-sh-s-" + str(0) + ".jpg")
cv2.imencode(".jpg", v)[1].tofile(
file_name + "-sh-v-" + str(0) + ".jpg")
运行方法
python test.py -i test.jpg
效果图片
最后的话:
我是一个工作10年的程序员,工作中经常会遇到需要查一些关键技术,但是很多技术名词的介绍都写的很繁琐,为什么没有一个简单的/5分钟能说清楚的博客呢. 我打算有空就写写这种风格的指南文档.CSDN上搜蓝色的杯子, 没事多留言,指出我写的不对的地方,写的排版风格之类的问题,让我们一起爱智求真吧.wisdomfriend@126.com是我的邮箱,也可以给我邮箱留言.