c++ 绘制函数图像_使用Matlab测量图像目标尺寸

8729ac64647b3daa9afabb5721c57e35.png

在传统的数字图像处理当中,边缘检测形态学为两门非常重要的技术,在笔者的第一篇文章中已经重点介绍了各种边缘检测算子,因此这次笔者将结合一些较为简单的形态学算法,使用Matlab为大家介绍一个很有意思的测量目标尺寸的小项目,效果如下

76281a83436ea5ea1497e15cd244cf22.png
图1 效果图

1.测距原理

在数字图像处理当中我们可知,在计算机眼中,每一张图片都实际上表现为一个庞大的矩阵,若在不知道测距物体距离的情况下,是不可能对图像中物体进行大小(size)的测量计算的,因此我们需要引入一个和比例尺类似的概念:pixels per metric ratio

意为给定度量单位的像素比率,在本篇文章中我们将给点度量单位设定为英寸(inch),可以理解为参考物的作用`,给定图像中一参考物大小,便可测得其它目标物体的尺寸大小

其中,参考物需要有两个重要性质:

性质1:参考物尺寸

我们应该知道物体的尺寸(就是宽或高)包括测量的单位(如mm、英寸等)

性质2:易于识别

我们应该能够很容易地在图片中找到参照物体,无论是基于物体的位置(例如,参考物体总是放在图片的左上角)还是通过外观(例如,独特的颜色或形状,不同与图片中的其他物体)。无论是哪种情况,我们的参照物都应该以某种方式具有唯一的可识别性。

在本篇文章中,我们将硬币作为我们的参考物,已知其尺寸大小为1 inch*1 inch,并且为满足性质2,我们确保其始终置于图像最左侧

47a9a1c72e171b6d0d1e820e624d847d.png
图2 测距原理

因此我们得到给定度量单位像素比例计算公式:

pixels per metric ratio = 硬币像素数/物体实际尺寸

已知硬币长宽均为1英寸,假设其在图像中像素宽为157px(基于其关联的检测框),得:

pixels per metric ratio = 157px/1.000in = 157px/in

通过使用这一比例,我们便可计算图像中其它物体的尺寸大小信息了

2.利用计算机视觉测量物体的大小

现在我们理解了pixels per metric ratio比率的含义,但我们还需要对目标进行检测进行检测框长宽的提取,这一步我们将用到诸如灰度图变换、边缘检测、形态学等算法

首先我们定义硬币长宽,并且读取原始图像

coin_width

71833abfeca271f5ae8870c6517dd423.png
图3 原始图像

之后我们使用rgb2gray(image)函数进行灰度图转换,并且通过imfilter(f, w,boundary_options)函数对图像进行高斯滤波,其中w为滤波器,由fspecial(type,parameters,sigma)生成,其中将type设为"gaussian",sigma设为1,代码及效果如下

%转换为灰度图像

c473314556b741d4129e04ba68e212aa.png
图4 高斯图像

对高斯滤波后的图像进行Canny边缘检测,使用edge(I,method,threshold),,其中I为输入图像,method为指定算法,文章中使用"canny"进行边缘检测,而threshold为阈值,通常设为0.1,具体想了解各边缘检测算法详解请看这篇文章

Rustle:数字图像图像处理:边缘检测(Edge detection)​zhuanlan.zhihu.com
cccc86d5bfc878461044b19ef078d501.png

边缘检测代码及效果如下所示

I3

a726b56f8353b1f0c2a81681eb6bb422.png
图5 Canny边缘检测图像

通过观察边缘图像可以发现各目标内部还具有较细的纹理,对后续八连通区域的检测造成较大干扰,因此我们可以通过孔洞填充操作去除内部纹理,其次提取孔洞填充图像外围边缘,最后使用形态学算法去除较小物体,具体代码如下:

% 孔洞填充

其中bwperim函数与传统的边缘检测概念不同,边缘检测为提取图像边缘特征图像,而bwperim只保留目标最外层边缘,bwareaopen(I4,150)意为去除图像中小于150px的八连通区域(至于为什么选择150,emmmm笔者是把它当成参数直接人为调的哈)

最后效果如下:

075ccc1f980785afe17bdcb3e0b396d6.png
图6 孔洞填充图像

4cb7ede9da37584e83ade1e0bd7506f4.png
图7 提取外围边缘

78e1b3f7a6f5cbb3f7b08920c50db660.png
图8 去除小物体

至此,我们便完成了对图像的处理阶段,接下来我们需要对物体进行标记,并且绘制相关的检测框图,其中我们使用 [labelpic,num] = bwlabel(I5,8)来对图像从左至右对目标进行标记,并配合find函数进行特定目标的操作,如接下来我们需要计算pixels per metric ratio,我们需要将最左边硬币目标提取出来,我们可以使用以下代码进行提取

[

其中r,c分别为目标对象(coin)的八连通行列坐标,然后我们使用函数minboundrect(c,r,'p')将得到的r,c进行最小外接矩形的计算,其中参数p表示按边长最小原则进行计算,最后使用minboxing()函数计算最小外接矩形的长宽,具体代码如下:

% 获取标记物体最小外接矩形坐标点

计算pixels per metric ratio:

% 单位英寸像素点比例计算
 
其中minboundrect与minboxing函数并不是Matlab官方函数,具体代码会在文末给出

我们使用同样的原理进行各目标最小外接矩形的计算,并使用line函数在图像中绘制出矩形框与中点连线

for 

最后,我们根据pixels per metric ratio与最小外接矩形长宽计算目标实际尺寸,并通过text函数在图像中进行显示,代码如下:

line

好了现在我们完成了所有工作,最终的效果图便是这样啦

76281a83436ea5ea1497e15cd244cf22.png
图9 效果图

最后在放两个动图让大家看看效果吧

103881f659584426b3a19c66eea979b1.gif
图10 效果演示

a995182429ed710e7072548e1d4be8d6.gif
图11 效果演示

如上图所示,我们已经成功的计算出图片中每个物体的尺寸

然而,并非所有的结果都是完美的,可能的原因:

  1. 拍摄的角度并非是一个完美的90°俯视。如果不是90°拍摄,物体的尺寸可能会出现扭曲
  2. 没有使用相机内在和外在参数来校准。当无法确定这些参数时,照片很容易发生径向和切向的透镜变形。执行额外的校准步骤来找到这些参数可以消除图片中的失真并得到更好的物体大小的近似值

参考

1.Measuring size of objects in an image with OpenCV

代码如下:

coin_width

minboundrect函数

function

minboxing函数

function

码字不易,各位看官点个赞再走呀嘻嘻嘻

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在VSCode,可以使用C语言来绘制函数图像。首先,我们需要使用图形库(例如graphics.h)来实现图形绘制的功能。但是,VSCode默认情况下是不支持C语言图形库的,需要借助其他工具来实现。下面提供两种可行的方法供您参考: 方法一:使用MinGW和Dev-C++: 1. 首先,下载并安装MinGW(MinGW是一个Windows平台的C/C++开发环境)。 2. 安装完成后,在VSCode打开终端,并输入命令`gcc -v`,确保MinGW已经正确安装。 3. 接下来,下载并安装Dev-C++(一个集成了MinGW的C/C++集成开发环境)。 4. 打开Dev-C++,创建一个新项目,在项目编写C代码,包括图形函数的调用和图像绘制过程。 5. 编写完成后,保存并编译代码,生成可执行文件。 6. 在VSCode终端,输入可执行文件的路径,并执行,即可在屏幕上看到函数图像绘制结果。 方法二:使用SDL库: 1. 首先,下载并安装SDL库(一个用于开发2D图形、音效、并支持多平台的库)。 2. 在VSCode打开终端,并输入命令`gcc -v`,确保MinGW已经正确安装。 3. 在VSCode创建一个新的C文件,并引入SDL库的头文件。 4. 在主函数,初始化SDL库,并设置图像窗口的大小和标题。 5. 使用SDL提供的相关函数来实现函数图像绘制,包括坐标和颜色的处理等。 6. 编写完成后,保存并编译代码,生成可执行文件。 7. 在VSCode终端,输入可执行文件的路径,并执行,即可在窗口看到函数图像绘制结果。 以上就是使用VSCode绘制函数图像的两种方法。通过使用MinGW和Dev-C++或SDL库,我们可以在VSCode进行C语言的图形编程,实现函数图像绘制。 ### 回答2: 要在VSCode绘制函数图像,可以遵循以下步骤: 1. 安装并配置C/C++插件:在VSCode的扩展市场搜索并安装C/C++插件。安装完成后,按下F1键,然后输入"C/C++: Edit Configurations",选择该选项以打开配置文件。找到"browse.path"一行,并确保其包含了C/C++的安装路径。 2. 创建C文件:在VSCode创建一个新的C文件,例如,给它命名为"function_graph.c"。在这个文件编写绘制函数图像的C代码。 3. 编写函数图像的C代码:在"function_graph.c"文件,编写绘制函数图像的C代码。你可以使用数学函数库,如math.h,并使用像"sin"、"cos"、"sqrt"等函数来定义要绘制函数。还可以使用循环结构来生成绘图的数据点。 4. 配置编译任务:按下Ctrl+Shift+B键,选择"终端-运行生成任务",然后选择“configure task”以创建一个新的任务。为该任务选择"gcc"编译器,并将文件名设置为"function_graph.c"。保存并关闭配置文件。 5. 编译并运行程序:按下Ctrl+Shift+B键,选择刚刚创建的编译任务,并等待编译器完成。 6. 查看函数图像:编译成功后,在VSCode的终端输入可执行文件的名称,然后按下Enter键来运行程序。这将在终端打印出函数图像的数据点。 7. 使用扩展插件绘制图像:在VSCode的扩展市场搜索并安装合适的扩展插件,如"GraphPlot"。然后按照插件的说明来使用它来绘制函数图像。 这样你就可以在VSCode绘制函数图像了。根据你所选择的方法,你可以在终端打印出图像的数据点,或者使用插件将函数图像直接显示在VSCode的界面。 ### 回答3: 要在VSCode绘制C语言函数图像,可以采用以下步骤: 1. 首先,确保已经安装了C/C++的开发环境。可以选择安装MinGW、GCC等编译器,并将其添加到系统的环境变量,以便在VSCode能够使用C语言的相关命令。 2. 在VSCode新建一个C语言源文件(.c扩展名),可以使用命令或者手动创建一个文件,并将文件保存在适当的位置。 3. 在源文件,编写C语言代码以绘制函数图像。可以使用C语言的绘图库,如graphics.h等,或者使用其他开源的图形库,如SDL等。根据具体需求,可以选择合适的库来实现图像绘制。 4. 在代码使用合适的函数来设置图形窗口的大小、颜色等属性,并通过绘图函数来画出函数图像。具体的代码会根据所选择的库而有所不同,可以参考相关的文档或示例代码来编写正确的绘图代码。 5. 编写完毕后,保存源文件,并在VSCode打开一个终端窗口。在终端使用相关的编译命令来将C源文件编译为可执行文件。例如,使用GCC编译器可以使用命令`gcc filename.c -o output`来将源文件编译为output可执行文件。 6. 编译成功后,使用终端的命令来运行生成的可执行文件。例如,使用命令`./output`来运行可执行文件,在图形窗口显示函数图像。 以上就是在VSCode绘制C语言函数图像的一般步骤。具体的实现方式会根据所选择的库而有所不同,可以根据实际需求来选择合适的绘图库和相应的代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值