jjzjj

OpenCV-几何形状颜色识别 #导入MD文档图片#

孙中明 2023-03-28 原文

题目

请编写程序将图像Image中的三角形找到,并且以接近于图像中心的三角形作为根节点,距离其最近的三角形作为其左节点,次近的作为其右节点,建立一个二叉树来表示和存储图中的三角形,其中二叉树中每个节点包括:三角形的位置、其父节点的位置(若为个节点,坐标为(-1,-1))、三角形的颜色、三角形的面积。 请输出二叉树

思路

  1. 先先识别三角形,就先转成二值图像, 然后使用轮廓发现findContours相关函数,提取与绘制轮廓,最后用approxPolyDP对其进行轮廓逼近,

  2. 然后对三角形找到中心点 ,需要用moments计算一阶几何距得到指定轮廓的中心位置

  3. 然后的到的三角形中心位置坐标可以用来得出三角形的坐标和颜色

  4. “以接近于图像中心的三角形作为根节点,距离其最近的三角形作为其左节点,次近的作为其右节点”在构成二叉树的时候(我印象中学习机器学习的时候貌似记得有个KNN算法,实现有点麻烦),这里我是直接用两点之间开方计算距离。

  5. 后面二叉树的,先按照距离进行排序,然后插入节点

  6. 打印节点

代码

# -*- coding: utf-8 -*- #引入必要工具 import cv2 as cv import numpy as np import math #计算距离 def caculateDistance(a, b): return math.sqrt(math.pow(a[0] - b[0], 2) + math.pow(a[1] - b[1], 2)) class Node: def __init__(self, pos, area, color): # 节点内容:面积,颜色,坐标,左子树,右子树,父节点 self.area = area self.color = color self.pos = pos self.left = None self.right = None self.Parent = None #添加左子树 def addLeft(self, l): self.left = l # 添加右子树 def addRight(self, r): self.right = r # 添加父节点 def GetParent(self): return self.Parent #定义树 class Tree: def __init__(self): self.root = None def addroot(self, root): self.root = root class ShapeAnalysis: def __init__(self): self.shapes = {'triangle': 0, 'rectangle': 0, 'polygons': 0, 'circles': 0} self.i = 0 def analysis(self, frame, tree): h, w, ch = frame.shape result = np.zeros((h, w, ch), dtype=np.uint8) # 二值化图像 print("start to detect lines...\n") gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY) ret, binary = cv.threshold(gray, 230, 255, cv.THRESH_BINARY_INV) triangles = {} cv.imshow("Binary Image", binary) out_binary, contours, hierarchy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) for cnt in range(len(contours)): # 提取与绘制轮廓 cv.drawContours(result, contours, cnt, (0, 255, 0), 2) # 轮廓逼近 epsilon = 0.012 * cv.arcLength(contours[cnt], True) approx = cv.approxPolyDP(contours[cnt], epsilon, True) # 分析几何形状 corners = len(approx) shape_type = [] if corners == 3: count = self.shapes['triangle'] count = count + 1 self.shapes['triangle'] = count shape_type = "三角形" # 求中心位置 mm = cv.moments(contours[cnt]) cx = int(mm['m10'] / mm['m00']) cy = int(mm['m01'] / mm['m00']) if shape_type == "三角形": cv.circle(result, (cx, cy), 3, (0, 0, 255), -1) # 计算颜色 color = frame[cy][cx] color_str = "(" + str(color[0]) + ", " + str(color[1]) + ", " + str(color[2]) + ")" # 计算面积 area = cv.contourArea(contours[cnt]) # 判断三角形 if shape_type == "三角形": n = Node([cx, cy], area, color) triangles[self.i] = n self.i = self.i + 1 print("-------------------------------------") print("第%d个三角形:"%self.i) print(" 坐标 %s 面积: %.3f 颜色: %s " % ((cx, cy), area, color_str)) print("-------------------------------------") cv.imshow("Analysis Result", self.draw_text_info(result)) center = [frame.shape[0] / 2, frame.shape[1] / 2] print("图片中心位置:%s"%center) print("-------------------------------------") dis = {} # 以接近于图像中心的三角形作为根节点, # 距离其最近的三角形作为其左节点,次近的作为其右节点 for j in range(4): dis[j] = caculateDistance(center, triangles[j].pos) for j in range(4): for k in range(4): if (dis[j] < dis[k]): temp = dis[k] dis[k] = dis[j] dis[j] = temp temp1 = triangles[k] triangles[k] = triangles[j] triangles[j] = temp1 for j in range(len(triangles)): print(dis[j]) print(triangles[j].pos) tree.addroot(triangles[0]) x = Node([-1, -1], 0, [-1, -1, -1]) triangles[0].Parent = x triangles[0].addLeft(triangles[1]) triangles[1].Parent = triangles[0] triangles[0].addRight(triangles[2]) triangles[2].Parent = triangles[0] triangles[1].addLeft(triangles[3]) triangles[3].Parent = triangles[1] # 3和2号没有子树,1号没有右子树 y = Node([0, 0], 0, [-1, -1, -1]) triangles[3].addLeft(y) triangles[3].addRight(y) triangles[2].addLeft(y) triangles[2].addRight(y) triangles[1].addRight(y) for k in range(4): print("-------------------------------------") print("第%d节点 面积%.3f 颜色%s 父节点%s 自己节点%s 左子树%s 右子树%s "% (k,(triangles[k].area),(triangles[k].color),(triangles[k].Parent.pos),(triangles[k].pos),(triangles[k].left.pos),(triangles[k].right.pos))) return self.shapes def draw_text_info(self, image): c1 = self.shapes['triangle'] cv.putText(image, "triangle: " + str(c1), (10, 20), cv.FONT_HERSHEY_PLAIN, 1.2, (255, 255, 255), 1) return image if __name__ == "__main__": src = cv.imread("D:/picture/11.png") tree = Tree() ld = ShapeAnalysis() ld.analysis(src, tree) cv.waitKey(-1)

结果

图像处理

控制台输出结果

Python 3.6.4 |Anaconda, Inc.| (default, Jan 16 2018, 10:22:32) [MSC v.1900 64 bit (AMD64)] on win32 runfile('C:/Users/Jackinsun/Desktop/untitled0.py', wdir='C:/Users/Jackinsun/Desktop') start to detect lines... ------------------------------------- 第1个三角形: 坐标 (436, 330) 面积: 1447.500 颜色: (195, 195, 195) ------------------------------------- 第2个三角形: 坐标 (99, 215) 面积: 1393.500 颜色: (76, 177, 34) ------------------------------------- 第3个三角形: 坐标 (315, 208) 面积: 965.500 颜色: (0, 243, 255) ------------------------------------- 第4个三角形: 坐标 (241, 101) 面积: 4813.500 颜色: (36, 28, 237) ------------------------------------- 图片中心位置:[208.0, 277.0] ------------------------------------- 125.39936203984452 [99, 215] 127.3184982632139 [315, 208] 179.06702655709677 [241, 101] 234.07904647789388 [436, 330] ------------------------------------- 第0节点 面积1393.500 颜色[ 76 177 34] 父节点[-1, -1] 自己节点[99, 215] 左子树[315, 208] 右子树[241, 101] ------------------------------------- 第1节点 面积965.500 颜色[ 0 243 255] 父节点[99, 215] 自己节点[315, 208] 左子树[436, 330] 右子树[0, 0] ------------------------------------- 第2节点 面积4813.500 颜色[ 36 28 237] 父节点[99, 215] 自己节点[241, 101] 左子树[0, 0] 右子树[0, 0] ------------------------------------- 第3节点 面积1447.500 颜色[195 195 195] 父节点[315, 208] 自己节点[436, 330] 左子树[0, 0] 右子树[0, 0]

参考资料

opencv findContours

python-opencv获取二值图像轮廓及中心点坐标

Python-opencv 图片颜色域的识别选取

Python OpenCV Color Detection Example

Simple shape detection – Opencv with Python 3

OpenCV中几何形状识别与测量

OpenCV Python Tutorial For Beginners 25 - Detect Simple Geometric Shapes using OpenCV in Python

有关OpenCV-几何形状颜色识别 #导入MD文档图片#的更多相关文章

  1. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  2. ruby-on-rails - Ruby on Rails - 为文本区域和图片生成列 - 2

    我是Rails的新手,所以请原谅简单的问题。我正在为一家公司创建一个网站。那家公司想在网站上展示它的客户。我想让客户自己管理这个。我正在为“客户”生成一个表格,我想要的三列是:公司名称、公司描述和Logo。对于名称,我使用的是name:string但不确定如何在脚本/生成脚手架终端命令中最好地创建描述列(因为我打算将其设置为文本区域)和图片。我怀疑描述(我想成为一个文本区域)应该仍然是描述:字符串,然后以实际形式进行调整。不确定如何处理图片字段。那么……说来话长:我在脚手架命令中输入什么来生成描述和图片列? 最佳答案 对于“文本”数

  3. ruby 诅咒颜色 - 2

    如何使用Ruby的默认Curses库获取颜色?所以像这样:puts"\e[0m\e[30;47mtest\e[0m"效果很好。在浅灰色背景上呈现漂亮的黑色。但是这个:#!/usr/bin/envrubyrequire'curses'Curses.noecho#donotshowtypedkeysCurses.init_screenCurses.stdscr.keypad(true)#enablearrowkeys(forpageup/down)Curses.stdscr.nodelay=1Curses.clearCurses.setpos(0,0)Curses.addstr"Hello

  4. ruby - Rails 3 的 RGB 颜色选择器 - 2

    状态:我正在构建一个应用程序,其中需要一个可供用户选择颜色的字段,该字段将包含RGB颜色代码字符串。我已经测试了一个看起来很漂亮但效果不佳的。它是“挑剔的颜色”,并托管在此存储库中:https://github.com/Astorsoft/picky-color.在这里我打开一个关于它的一些问题的问题。问题:请建议我在Rails3应用程序中使用一些颜色选择器。 最佳答案 也许页面上的列表jQueryUIDevelopment:ColorPicker为您提供开箱即用的产品。原因是jQuery现在包含在Rails3应用程序中,因此使用基

  5. ruby - 检查是否通过 require 执行或导入了 Ruby 程序 - 2

    如何检查Ruby文件是否是通过“require”或“load”导入的,而不是简单地从命令行执行的?例如:foo.rb的内容:puts"Hello"bar.rb的内容require'foo'输出:$./foo.rbHello$./bar.rbHello基本上,我想调用bar.rb以不执行puts调用。 最佳答案 将foo.rb改为:if__FILE__==$0puts"Hello"end检查__FILE__-当前ruby​​文件的名称-与$0-正在运行的脚本的名称。 关于ruby-检查是否

  6. 报告回顾丨模型进化狂飙,DetectGPT能否识别最新模型生成结果? - 2

    导读语言模型给我们的生产生活带来了极大便利,但同时不少人也利用他们从事作弊工作。如何规避这些难辨真伪的文字所产生的负面影响也成为一大难题。在3月9日智源Live第33期活动「DetectGPT:判断文本是否为机器生成的工具」中,主讲人Eric为我们讲解了DetectGPT工作背后的思路——一种基于概率曲率检测的用于检测模型生成文本的工具,它可以帮助我们更好地分辨文章的来源和可信度,对保护信息真实、防止欺诈等方面具有重要意义。本次报告主要围绕其功能,实现和效果等展开。(文末点击“阅读原文”,查看活动回放。)Ericmitchell斯坦福大学计算机系四年级博士生,由ChelseaFinn和Chri

  7. Matlab imread()读到了什么 (浅显 当复习文档了) - 2

    matlab打开matlab,用最简单的imread方法读取一个图像clcclearimg_h=imread('hua.jpg');返回一个数组(矩阵),往往是a*b*cunit8类型解释一下这个三维数组的意思,行数、数和层数,unit8:指数据类型,无符号八位整形,可理解为0~2^8的数三个层数分别代表RGB三个通道图像rgb最常用的是24-位实现方法,即RGB每个通道有256色阶(2^8)。基于这样的24-位RGB模型的色彩空间可以表现256×256×256≈1670万色当imshow传入了一个二维数组,它将以灰度方式绘制;可以把图像拆分为rgb三层,可以以灰度的方式观察它figure(1

  8. 旋转矩阵的几何意义 - 2

    点向量坐标矩阵的几何意义介绍旋转矩阵的几何含义之前,先介绍一下点向量坐标矩阵的几何含义点:在一维空间下就是一个标量,如同一条直线上,以任意某一个位置为0点,以一定的尺度间隔为1,2,3...,相反方向为-1,-2,-3...;如此就形成了一维坐标系,这时候任何一个点都可以用一个数值表示,如点p1=5,即即从原点出发沿着x轴正方向移动5个尺度;点p2=-3,负方向移动3个尺度;     在一维坐标系上过原点做垂直于一维坐标系的直线,则形成了二维坐标系,此时描述一个点需要两个数值来表示点p3=(3,2),即从原点出发沿着x轴正方向移动3个尺度,在此基础上沿着y轴正方向移动两个尺度的位置就是点p3。

  9. Vscode+Cmake配置并运行opencv环境(Windows和Ubuntu大同小异) - 2

    之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m

  10. [Vuforia]二.3D物体识别 - 2

    之前说过10之后的版本没有3dScan了,所以还是9.8的版本或者之前更早的版本。 3d物体扫描需要先下载扫描的APK进行扫面。首先要在手机上装一个扫描程序,扫描现实中的三维物体,然后上传高通官网,在下载成UnityPackage类型让Unity能够使用这个扫描程序可以从高通官网上进行下载,是一个安卓程序。点到Tools往下滑,找到VuforiaObjectScanner下载后解压数据线连接手机,将apk文件拷入手机安装然后刚才解压文件中的Media文件夹打开,两个PDF图打印第一张A4-ObjectScanningTarget.pdf,主要是用来辅助扫描的。好了,接下来就是扫描三维物体。将瓶

随机推荐