在周末,我写了一个试图确定刺绣箍图像中使用的DMC线程的程序。我没有在大学拍摄电脑视觉课程 - 我之前也没有使用过OpenCV - 所以要学习一些事情很有趣,我希望你能从我的学习中学到。
当我的妻子想了解一些在r /刺绣的篮子里使用了哪些颜色时,这一切都开始了。因此,我开始了过度设计的解决方案:猜测的Python CLI,然后覆盖给定图像上的DMC线程调色板。
要开始,我审查了100个篮球最近发布到R /刺绣,并看到它们直接拍摄了中心靠近中心的箍。具有相当均匀的结构,我认为一点电脑视觉脚本可以帮助我。篮球是近乎完美的圈子使它们成为OpenCV的Hough圈变换的伟大目标。然而,照片非常嘈杂。很多东西出现在圈子中,由于高分辨率,该功能花了很长时间。
因此,为了更好地瞄准箍区域,我使用了一系列破坏性滤波器 - 将图像缩小,转换为灰色,然后应用以下内容:高斯本金,中美洲,适应性的,侵蚀,扩张。正如我们所看到的,这使得箍与Houghcircles更可识别。
在我拥有的100 r /绣花帖子上运行程序后,调整这些过滤器的值。我构建的程序的完整源代码可以在HEALEYCODES / HARVIZE-VISION中找到。
def apply_destructive_filters(图像):"""应用一系列破坏性滤波器,目的是对Houghcircles功能更加明显的圆圈。 """ kernel = np .ones((5,5),np .uint8)filtered_image = cv2 .cvtcolor(图像,cv2 .color_bgr2gray)filtered_image = cv2 .gaussianblur(filtered_image,(5,5),0)filtered_image = cv2 .medianblur( filtered_image,5)filtered_image = cv2 .adaptivethreshold(filtered_image,255,cv2 .adaptive_thresh_gaussian_c,cv2 .thresh_binary,11,3.5)filtered_image = cv2 .erode(filtered_image,内核,iterations = 1)filtered_image = cv2 .dilate(filtered_image,ernel,迭代= 1)返回filtered_image
可以找到多个圆圈是常见的。当发生这种情况时,我挑选最大,最中心的。这可以在上一个图像中看到。有效的圆圈是绿色的。我有时发现部分圆圈匹配箍标准(大和中央)。然而,这些是背景形状。用户很少发布在箍的图像中放大,因此我丢弃了超越边缘的圆圈。
有效圆圈通常包括箍边框的一部分。我不想将边界的颜色视为一个螺纹,所以我缩小了箍区域1%以隐藏它。
有454个DMC螺纹颜色。他们被称为米色灰色ult dk这样的东西。目标是采取拍摄线程的RBG颜色并找到最接近的匹配DMC颜色。我不考虑照明条件(您将如何做到这一点?)降低结果的准确性。我的程序找到了一些线程并猜测其他线程。对于最近的颜色查找,我使用了来自Scipy.spatial.kdtree的K-D树。
def rgb_to_dmc(r,g,b):tree = sp .kdtree(rgb_colors)_,结果=树.query((r,g,b))#返回`rgb_colors`返回结果的索引
当我尝试在箍区域中的每个像素上打电话时,它构建的调色板太多了。当图像中有一种深红色线时,调色板将有六个或七种不同的DMC红色。我需要将组颜色更好地一起,因此我量化了图像。
#https://stackoverflow.com/a/20715062 def量化_image(图像,div = 64):"""减少图像中使用的不同颜色的数量。 """量化=图像// div * div + div // 2返回量化
压缩颜色空间,如此意味着,而不是找到多个深红色,我们只找到一个(希望正确的黑色)。这是应用上述功能之前和之后的图像。
为高分辨率图像中的每个像素调用K-D树查找很慢。对于我在此帖子中使用的示例图像,有600k像素(这意味着相同的查找数量),但只有30种不同的颜色。添加缓存是一个禁智的人。 Python建于最近使用的(LRU)缓存的建立得很好,现在我们的600K呼叫在不断的时间内执行。
使用DMC识别号码,我将调色板绘制在图像上。调色板也被发送到标准输出(例如,例如,#647 Beaver Gray Med 15.81%)
由于在线文档和博客帖子的数量,我发现使用OpenCV的API非常直接。每当我有一个问题时,一个搜索给我带来了一个模糊相关的答案。也许我低估了图书馆的普及。最困难的部分(一如既往地)是询问的正确问题。
#覆盖图像顶部的调色板,w,_ = reation_image .shapesize = int(w / len(filtered))y = idx的大小,枚举中的颜色(过滤):b,g,r =(dmc_colors [颜色[0]] ["蓝色"],dmc_colors [color [0]] ["绿色"],dmc_colors [color [0]] ["红色" ],)cv2 .rectangle(original_image,(size * idx,0),((size * idx)+大小,大小),(b,g,r), - 1)cv2 .puttext(original_image,dmc_colors [color [color [ 0] ["牙线"],(size * idx,size-7),cv2 .font_hershey_simplex,0.5,(255 - b,255 - g,255 - r),1,)
我试着在Github上公开做大部分工作。这有助于人们(更多的人比我预期的更多人提供帮助),但我最感兴趣的是它对扩大我的志同道合的制造商网络的影响。在任何工作中收到留言,问题或公关是一种喜悦。
当我制作一个存储库公共时,我的目标是拥有一个可易化的自述文件和一些测试。对于此项目,DMC颜色查找是由测试的单元,示例图像用于端到端测试。我添加了一个GitHub动作,以便让人们检查他们的PRS是通过的(当我在手机上编辑源文件时,我也很高兴收到一封电子邮件!)。这个项目不太可能看到合作,因为它是我的学习项目,而不是一般工具。这是我的洁具。另外,它并没有真正的工作。
最近,我一直在使用Mypy为我的开源Python代码。它一直捕获错误并强制执行更好的代码模式。但可悲的是,我无法让OpenCV类型的存根工作,所以我删除了mypy。从我通常的github行动。
最后,我将使用像麻省理工学院那样的开源许可证完成。我讨厌某人从我的玩具项目中学习一些东西,但不能使用它。我总是试着介绍我的工作,就好像有它的最终用户一样 - 一个过程让我的代码更容易,而不是我没有。
评论或问题? 我喜欢通过电子邮件与读者交谈。 我写了关于代码。 将我的帖子,项目和个人更新直接到您的收件箱!