目录

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. Linux 文件操作接口

    目录 Linux 文件操作接口 C语言文件操作接口 C语言文件描述 fopen() r模式打开文件 w模式打开文件 a模式打开文件 其他模式类似 fclose() fwrite() fread() 系 ...

  2. 沁恒CH32V003F4P6 开发板上手报告和Win10环境配置

    CH32V003 沁恒最近推出的低价CH32V003系列, 基于青稞RISC-V2A内核, 48MHz主频, 2KB SRAM, 16KB Flash, 工作电压兼容3.3V和5V. 主要参数如下 S ...

  3. Linux文件属性与管理

    文件或目录属性主要包括: 索引节点,inode 文件类型 文件权限 硬链接个数 归属的用户和用户组 最新修改时间 查看命令 ls -lhi /opt 图解: Inode索引节点号,(人的身份证,家庭地 ...

  4. JS逆向实战5--JWT TOKEN x_sign参数

    什么是JWT JWT(JSON WEB TOKEN):JSON网络令牌,JWT是一个轻便的安全跨平台传输格式,定义了一个紧凑的自包含的方式在不同实体之间安全传输信息(JSON格式).它是在Web环境下 ...

  5. 洛谷 P3201 梦幻布丁 题解

    (这篇题解可能没什么营养,主要是记录一下我用map乱搞启发式合并的神奇做法) 首先我们知道,我们肯定要用一堆集合维护每一种数当前的位置,并支持合并和数连续出现的段数两种操作 我发现这个东西并不好搞,但 ...

  6. 1.python基础使用

    1.git简介 git是一个免费的开源的分布式版本控制系统,可以快速高效的处理从小型到大型项目的所有事务 在实际工作中可以保留项目的所有版本,可以快速的实现版本的回滚和修改 git整体可以分为4个区域 ...

  7. c语言内存四区、数据存储范围和内存存储方向

    (1)代码区通常是共享只读(代码无法修改)的,即可以被其他的程序调用,例如运行两个qq,除了数据不一样,代码都是一样的, 每次运行qq,都会将代码和数据加载到内存中,除了数据,每次加载的代码都是一样的 ...

  8. 【云原生 · Kubernetes】Taint和Toleration(污点和容忍)

    个人名片: 因为云计算成为了监控工程师‍ 个人博客:念舒_C.ying CSDN主页️:念舒_C.ying Taint和Toleration(污点和容忍) 概念 添加多个tainit(污点) 使用例子 ...

  9. 单例模式实现的多种方式、pickle序列化模块、选课系统需求分析等

    目录 单例模式实现的多种方式 方式一: 方式二: 方式三 方式四 pickle序列化模块 选课系统需求分析 功能提炼 选课系统架构设计 三层架构 选课系统目录搭建 选课系统功能搭建 单例模式实现的多种 ...

  10. Day20:继承详解

    继承的理解 继承:对类进行抽象化:也就是将存在的类构造成新的类: 比如说学生是一个类,老师是一个类,那么我们可以将学生类和老师类收纳进人这个类:那么学生和老师则为子类(派生类).人为父类(基类):子类 ...