OpenCV计算机视觉开发入门与实践<四十>:自动识别物体数量

摘要 :本文介绍基于 OpenCV 的物体计数实现方法。首先讲解物体计数的基本原理------基于形态学与距离变换的分水岭算法,并给出整体实现思路;随后详细说明如何在图像上绘制文字,包括 cv2.putText 函数的基本用法、在定义画布上绘制文字,以及解决灰度图无法直接显示彩色文本的方法;最后通过一个完整的药片计数示例,演示从图像读取、形态学处理、二值化、轮廓提取到计数标注的完整流程。

  在机器视觉中,有时需要对产品进行检测和计数。物体计数在生活中的应用非常广泛,例如每天都要吃维生素片,但有时候忘了今天有没有吃过,就想对瓶子里的药片计

数。本章就来介绍一下机器视觉检测和计数的实现。

1.物体计数基本原理

  本章所说的物体计数是基于形态学的物体检测和计数,是在形态学的基础上衍生出的基于距离变换的分水岭算法,效果更具普遍性。至于什么是形态学,这里不再赘述,因为本章是应用章节,不会讲很多理论。物体计数的整体实现思路如下:

(1)读取图片。

(2)形态学处理(在二值化前进行适度形态学处理,效果俱佳)。

(3)二值化。

(4)提取轮廓(进行药片分割)

(5)获取轮廓索引,并筛选所需要的轮廓。

(6)画出轮廓,显示计数。

2.在图像上绘制文字

  为了方便统计物品,我们在物品计数的结果上通常要写上该物品的序号,这就需要在图像上绘制字符文字。在OpenCV中,调用cv2.putText函数可添加文字到指定位置。它对于需要在图片中加入文字的场景,提供了一种比较直接、方便的方式。注意:OpenCV不支持显示中文字符,使用cv2.putText添加的文本字符串不能包含中文字符(包括中文标点

符号)。

【例16.1】在现成图片上绘制英文字符

cpp 复制代码
#include "opencv2/opencv.hpp"
using namespace cv;
int main()
{
	Mat img = imread("lena.png"); //读取彩色图像(BGR)
	putText(img, "lena", Size(100, 40), FONT_HERSHEY_COMPLEX, 1, (0, 255, 0), 2, LINE_AA);
	imshow("test", img); //显示叠加图像
	waitKey();  //等待按键命令

	return 0;
}

【例16.2】在定义画布上画文字

cpp 复制代码
#include "opencv2/opencv.hpp"
using namespace cv;
int main()
{
	// 创建一个空的8位单通道灰度图像,大小为100x300
	Mat txtImage(100, 300, CV_8UC1, Scalar(0));
	txtImage.setTo(Scalar(128)); //这句可以设置其它颜色,现在设置灰色
	putText(txtImage, "hello world", Size(20, 30), FONT_HERSHEY_COMPLEX, 1, (255, 255, 255), 2);  //在画布上画字符串hello world
	imshow("result", txtImage);//显示图像
	waitKey();  // 等待按键命令

	return 0;
}

OpenCV的putText函数需要一个颜色参数,如果直接传递一个灰度图作为背景图像,

文本可能不会显示任何颜色。这是因为OpenCV中的颜色通常以BGR格式表示,而不是常

见的RGB格式。在灰度图中,每个像素只有一个灰度值,没有色彩信息。解决方法是在

绘制文本之前,将灰度图转换为BGR图像。我们可以先调用cvtColor函数将灰度图转换为

BGR图像,再使用putText函数。看下面的例子。

【例16.3】在灰度图上使用putText函数

cpp 复制代码
#include "opencv2/opencv.hpp"
using namespace cv;
#include <opencv2/opencv.hpp>

int main() {
	// 创建一个空白的黑色背景图像
	Mat img(100, 300, CV_8UC1, Scalar(0, 0, 0));
	// 设置文本内容
	std::string text = "Hello, OpenCV!";
	Mat bgr_image;
	// 将灰度图转换为BGR图像
	cvtColor(img, bgr_image, COLOR_GRAY2BGR);
	// 设置文本起始坐标(左下角点)
	Point textOrg(10, 50);
	// 设置文本字体
	int fontFace = FONT_HERSHEY_SIMPLEX;
	// 设置字体缩放比例
	double fontScale = 1;
	// 设置文本颜色,使用BGR格式
	Scalar color(255, 0, 255); // 白色文本
	// 设置文本线条类型和粗细
	int thickness = 2;
	// 绘制文本
	putText(bgr_image, text, textOrg, fontFace, fontScale, color, thickness);
	// 显示图像
	imshow("Image with Text", bgr_image);
	waitKey(0);
	return 0;
}

3.代码实现药片计数

【例16.4】实现药片计数

cpp 复制代码
#include "opencv2/opencv.hpp"
using namespace cv;
#include <iostream>
using namespace std;

int main(int argc, char** argv)
{
	Mat src, src_binary, dst, src_distance;
	src = imread("med.png");//读取药片图像文件,第二个参数省略,则表示返回彩色图像
	imshow("src", src);//显示源图像
	Mat kernel = getStructuringElement(MORPH_RECT, Size(22, 22), Point(-1, -1));
	morphologyEx(src, dst, MORPH_OPEN, kernel);//执行形态学开运算操作
	imshow("morphology", dst);//显示形态学开运算后的图像
	cvtColor(dst, dst, COLOR_RGB2GRAY); //将RGB格式的图像转换为灰度图像
	threshold(dst, src_binary, 100, 255, THRESH_OTSU);//进行图像阈值分割
	imshow("binary", src_binary);//显示二值化后图像
	vector<vector<Point>> contours;
	findContours(src_binary, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point(0, 0));
	RNG rng(12345);//为了后续使用随机函数,这里先设置随机数种子
	double area;
	Point2i PL;
	for (size_t i = 0; i < contours.size(); i++)
	{
		area = contourArea(contours[i]);//用于计算图像轮廓的面积,参数是图像的轮廓点
		if (area < 500)continue;  //如果面积小于500
		PL = contours[i].front();
		Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));//得到一个随机颜色值
		drawContours(src, contours, i, color, 2, 8);
		putText(src, to_string(i), PL, FONT_HERSHEY_COMPLEX, 1, color, 2);
	}
	imshow("number of drugs", src);
	waitKey(0);
	return 0;
}
相关推荐
火山引擎和TA的超级拍档们5 小时前
产品情报局 04|客服Agent:大模型时代的智能客服新范式
大数据·人工智能
richard_first5 小时前
第19章 RAG(Retrieval-Augmented Generation)
人工智能·深度学习·语言模型·自然语言处理·transformer
别动我齐刘海5 小时前
简历技术栈全面复习——UDP / TCP / CAN / ZMQ / Protobuf 通信工程
网络·c++·python·tcp/ip·机器学习·udp·github
2301_801821715 小时前
推进语义文本相似性建模:一个具有平移ReLU和平滑 K2损失的回归框架
人工智能
IT_陈寒5 小时前
我花3小时debug,就因为JavaScript这个隐式转换坑
前端·人工智能·后端
我是小白呀5 小时前
23-AI说可以开通以后呢:权限、审批、审计与执行门禁
人工智能·workflow
2401_890095615 小时前
武汉企业AI私有化部署验收需核对哪些日志字段?
人工智能·验收标准·武汉自动意志科技有限公司·智钳ai智能体聚合平台·企业ai私有化部署·日志字段
北京中科新远科技5 小时前
AI网卡五层检查法:协议、PCIe、NUMA、端口与验收
服务器·网络·人工智能
小苑同学5 小时前
Introduction怎么写
人工智能
径硕科技JINGdigital5 小时前
企业希望使用OpenAI ChatGPT系列模型构建业务应用,推荐通过哪些云平台接入和部署?
人工智能·其他