目录

1 名词解释

2 在OpenCV中查找Blob质心的步骤

3 图像多个blob下的质心获取

4 参考


在中学,我们学习了几何的中各种平面图形。找到标准平面图形的中心(几何中心)比较容易,如圆形,方形,三角形,椭圆形等。中心是几何名词,质心是物理名词。质心是针对实物体而言的,而几何中心是针对抽象几何体而言的,对于密度均匀标准形状的物体,质心和几何中心重合。

但是当要找到任意形状的质心时,就不那么容易了。

在处理图像时,很多时候需要找到质心。在这篇文章中,我们将首先讨论如何找到任意形状blob的质心,然后我们将转向多个blob的情况。

工程代码:

https://download.csdn.net/download/luohenyj/11025933

https://github.com/luohenyueji/OpenCV-Practical-Exercise

1 名词解释

(1)blob

blob在机器视觉中是指图像中的具有相似颜色、纹理等特征所组成的一块连通区域。。在这篇文章中,我们的目标是在Python和C ++中使用OpenCV找到blob的中心。

(2)质心

一个平面图形的质心是平面图形所有点的算术平均值(即平均值)。假设一个平面图形由n个点xi组成,那么质心由下式给出

在图像处理和计算机视觉领域中,每个平面图形由像素点构成,并且质心坐标为构成平面图形的所有像素点坐标的加权平均。

(3)图像矩

在OpenCV,我们用blob来称呼平面图形。我们可以在OpenCV中使用图像矩找到blob的中心。图像矩是图像像素值的加权平均值,借助它我们可以找到图像的一些特定属性,如半径,面积,质心等。为了找到图像的质心,我们通常将其二值化然后找到它的质心。质心由下式给出: -

Cx是质心的x坐标,Cy是质心的y坐标。M表示图像几何矩。注意M00可能等于0

其中图像矩计算如下:

2 在OpenCV中查找Blob质心的步骤

要找到blob的质心,我们将执行以下步骤: -

1.将图像转换为灰度图。

2.对图像执行二值化。

3.计算图像矩后找到图像的中心。

单个blob的质心寻找。pch为预编译文件

C++代码:


#include "pch.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include <stdio.h>
#include <stdlib.h> using namespace cv;
using namespace std; int main()
{
String img_path = "./image/circle.png";
Mat src, gray, thr; src = imread(img_path); // convert image to grayscale 获取灰度图
cvtColor(src, gray, COLOR_BGR2GRAY); // convert grayscale to binary image 二值化
threshold(gray, thr, 0, 255, THRESH_OTSU); // find moments of the image 提取二值图像矩,true表示图像二值化了
Moments m = moments(thr, true);
Point p(m.m10 / m.m00, m.m01 / m.m00); // coordinates of centroid 质心坐标
cout << Mat(p) << endl; // show the image with a point mark at the centroid 画出质心
circle(src, p, 5, Scalar(128, 0, 0), -1);
imshow("show", src);
waitKey(0);
return 0;
}

python代码:

#coding=utf-8
import cv2
import numpy as np # read image through command line
img = cv2.imread('./image/circle.png') # convert image to grayscale image
gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # convert the grayscale image to binary image
ret,thresh = cv2.threshold(gray_image,127,255,0) # calculate moments of binary image
M = cv2.moments(thresh) # calculate x,y coordinate of center
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"]) # put text and highlight the center
cv2.circle(img, (cX, cY), 5, (255, 255, 255), -1)
cv2.putText(img, "centroid", (cX - 25, cY - 25),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2) # display the image
cv2.imshow("Image", img)
cv2.waitKey(0)

结果如下所示:

3 图像多个blob下的质心获取

找到一个blob的质心非常容易,但是如果Image中有多个blob,我们将不得不使用findContours来查找图像中的轮廓数量并找到每个轮廓的中心。然后再计算几何矩。

C++代码:

#include "pch.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include <stdio.h>
#include <stdlib.h> using namespace cv;
using namespace std; RNG rng(12345); void find_moments(Mat src); int main()
{
String img_path = "./image/multiple.png";
/// Load source image, convert it to gray
Mat src, gray;
src = imread(img_path); cvtColor(src, gray, COLOR_BGR2GRAY); //显示原图
namedWindow("Source", WINDOW_AUTOSIZE);
imshow("Source", src); // call function to find_moments 寻质心函数
find_moments(gray); waitKey(0);
return(0);
} void find_moments(Mat gray)
{
Mat canny_output;
//各个轮廓的点集合
vector<vector<Point> > contours;
//轮廓输出结果向量
vector<Vec4i> hierarchy; /// Detect edges using canny 边缘算子提取轮廓
Canny(gray, canny_output, 50, 150, 3);
// Find contours 寻找轮廓 RETR_TREE表示提取所有轮廓
findContours(canny_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0)); /// Get the moments 图像矩
vector<Moments> mu(contours.size());
//求取每个轮廓的矩
for (int i = 0; i < contours.size(); i++)
{
mu[i] = moments(contours[i], false);
} /// Get the centroid of figures. 轮廓质点
vector<Point2f> mc(contours.size());
for (int i = 0; i < contours.size(); i++)
{
mc[i] = Point2f(mu[i].m10 / mu[i].m00, mu[i].m01 / mu[i].m00);
} /// Draw contours
//画轮廓
Mat drawing(canny_output.size(), CV_8UC3, Scalar(255, 255, 255)); for (int i = 0; i < contours.size(); i++)
{
Scalar color = Scalar(167, 151, 0);
//画轮廓
drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point());
//画质心
circle(drawing, mc[i], 4, color, -1, 7, 0);
} /// Show the resultant image
namedWindow("Contours", WINDOW_AUTOSIZE);
imshow("Contours", drawing);
waitKey(0);
}

python代码:

#coding=utf-8
import cv2
import numpy as np img = cv2.imread('./image/multiple.png') # convert the image to grayscale
gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# convert the grayscale image to binary image
ret,thresh = cv2.threshold(gray_image,127,255,0) # find contour in the binary image
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
# find contour in the binary image(opencv4)
#binary, contours, opt = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
for c in contours:
# calculate moments for each contour
M = cv2.moments(c)
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"]) # calculate x,y coordinate of center
cv2.circle(img, (cX, cY), 5, (255, 255, 255), -1)
cv2.putText(img, "centroid", (cX - 25, cY - 25),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2) # 3.4.1 im2, contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
# 3.2.0 im2, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) # display the image
cv2.imshow("Image", img)
cv2.waitKey(0)

结果:

4 参考

https://www.learnopencv.com/find-center-of-blob-centroid-using-opencv-cpp-python/

[OpenCV实战]9 使用OpenCV寻找平面图形的质心的更多相关文章

  1. [OpenCV实战]50 用OpenCV制作低成本立体相机

    本文主要讲述利用OpenCV制作低成本立体相机以及如何使用OpenCV创建3D视频,准确来说是模仿双目立体相机,我们通常说立体相机一般是指双目立体相机,就是带两个摄像头的那种(目就是指眼睛,双目就是两 ...

  2. [OpenCV实战]48 基于OpenCV实现图像质量评价

    本文主要介绍基于OpenCV contrib中的quality模块实现图像质量评价.图像质量评估Image Quality Analysis简称IQA,主要通过数学度量方法来评价图像质量的好坏. 本文 ...

  3. [OpenCV实战]46 在OpenCV下应用图像强度变换实现图像对比度均衡

    本文主要介绍基于图像强度变换算法来实现图像对比度均衡.通过图像对比度均衡能够抑制图像中的无效信息,使图像转换为更符合计算机或人处理分析的形式,以提高图像的视觉价值和使用价值.本文主要通过OpenCV ...

  4. [OpenCV实战]45 基于OpenCV实现图像哈希算法

    目前有许多算法来衡量两幅图像的相似性,本文主要介绍在工程领域最常用的图像相似性算法评价算法:图像哈希算法(img hash).图像哈希算法通过获取图像的哈希值并比较两幅图像的哈希值的汉明距离来衡量两幅 ...

  5. [OpenCV实战]47 基于OpenCV实现视觉显著性检测

    人类具有一种视觉注意机制,即当面对一个场景时,会选择性地忽略不感兴趣的区域,聚焦于感兴趣的区域.这些感兴趣的区域称为显著性区域.视觉显著性检测(Visual Saliency Detection,VS ...

  6. [OpenCV实战]44 使用OpenCV进行图像超分放大

    图像超分辨率(Image Super Resolution)是指从低分辨率图像或图像序列得到高分辨率图像.图像超分辨率是计算机视觉领域中一个非常重要的研究问题,广泛应用于医学图像分析.生物识别.视频监 ...

  7. [OpenCV实战]19 使用OpenCV实现基于特征的图像对齐

    目录 1 背景 1.1 什么是图像对齐或图像对准? 1.2 图像对齐的应用 1.3 图像对齐基础理论 1.4 如何找到对应点 2 OpenCV的图像对齐 2.1 基于特征的图像对齐的步骤 2.2 代码 ...

  8. [OpenCV实战]52 在OpenCV中使用颜色直方图

    颜色直方图是一种常见的图像特征,顾名思义颜色直方图就是用来反映图像颜色组成分布的直方图.颜色直方图的横轴表示像素值或像素值范围,纵轴表示该像素值范围内像素点的个数或出现频率.颜色直方图属于计算机视觉中 ...

  9. [OpenCV实战]33 使用OpenCV进行Hough变换

    目录 1 什么是霍夫变换 1.1 应用霍夫变换以检测图像中的线条 1.2 累加器 1.3 线条检测 1.4 圆环的检测 2 代码 3 参考 1 什么是霍夫变换 霍夫变换是用于检测图像中的简单形状(诸如 ...

随机推荐

  1. 换工作?试试远程工作「GitHub 热点速览 v.22.40」

    近日,潜在某个技术交流群的我发现即将毕业的小伙伴在焦虑实习.校招,刚好本周 GitHub 热榜有个远程工作项目.不妨大家换个思路,"走"出去也许有更多的机会.当然,除了全球的远程工 ...

  2. MySQL基础、MySQL安装和MariaDB安装

    MySQL基础 目录 MySQL基础 关系型数据库介绍 数据结构模型 RDBMS专业名词 关系型数据库的常见组件 SQL语句 MySQL安装与配置 MySQL安装 MariaDB安装 关系型数据库介绍 ...

  3. Golang可能会踩的58个坑之初级篇

    前言 Go 是一门简单有趣的编程语言,与其他语言一样,在使用时不免会遇到很多坑,不过它们大多不是 Go 本身的设计缺陷.如果你刚从其他语言转到 Go,那这篇文章里的坑多半会踩到. 如果花时间学习官方 ...

  4. 『现学现忘』Git后悔药 — 32、revert撤销(一)

    目录 1.Git的三种后悔药 2.revert命令原理 3.revert命令的使用 (1)移除某次提交的修改 (2)revert命令说明 1.Git的三种后悔药 在Git中后悔药有三种:amend.r ...

  5. 后端框架的学习----mybatis框架(9、多对一处理和一对多处理)

    9.多对一处理和一对多处理 #多对一 <!--按照结果集嵌套查询--> <select id="getAllStudent1" resultMap="S ...

  6. 论文解读(GLA)《Label-invariant Augmentation for Semi-Supervised Graph Classification》

    论文信息 论文标题:Label-invariant Augmentation for Semi-Supervised Graph Classification论文作者:Han Yue, Chunhui ...

  7. 教你用canvas打造一个炫酷的碎片切图效果

    前言 今天分享一个炫酷的碎片式切图效果,这个其实在自己的之前的博客上有实现过,本人觉得这个效果还是挺炫酷的,这次还是用我们的canvas来实现,代码量不多,但有些地方还是需要花点时间去理解的,需要点数 ...

  8. 【JavaWeb】学习笔记——JSP

    概念 全称:Java Server Pages, Java服务端页面 描述:一种动态的网页技术,可以在其中定义HTML.JS.CSS等静态内容,以及Java代码的动态内容 说明:JSP = HTML ...

  9. .Net Core&RabbitMQ限制循环消费

    前言 当消费者端接收消息处理业务时,如果出现异常或是拒收消息将消息又变更为等待投递再次推送给消费者,这样一来,则形成循环的条件. 循环场景 生产者发送100条消息到RabbitMQ中,消费者设定读取到 ...

  10. 栈溢出漏洞利用流程——以syncbrs为例

    0x1 缓冲区溢出漏洞攻击简介 缓冲区溢出攻击是针对程序设计缺陷,向程序输入缓冲区写入使之溢出的内容(通常是超过缓冲区能保存的最大数据量的数据),从而破坏程序的堆栈,使程序转而执行其他指令,以达到攻击 ...