利用OpenCV求取图像的重心

转自:http://blog.csdn.net/lxiaoxiaot/article/details/6539834

不规则区域的矩,表示把一个归一化的灰度级图像函数理解为一个二维随机变量的概率密度。

这个随机变量的属性可以用统计特征--矩(Moments)来描述。通过假设非零的像素值表示区域,矩可以用于二值或灰度级的区域描述。

Mpq = sigma(i)sigma(j) ijf(i,j)

其中x,y,i,j是区域点的坐标(在数字图像中的像素坐标)。

令Xc,Yc表示区域重心的坐标,则:

Xc = M10/M00;

Yc = M01/M00;

在二值图像的情况下,M00表示区域的面积。

OpenCV中可以使用函数cvMoments来计算二值图像的矩信息。

使用函数cvGetSpatialMoment获得指定维的矩信息。

例如:

// 计算二值化图像imgYellowThresh中物体的重心坐标

CvMoments *moments = (CvMoments*)malloc(sizeof(CvMoments));

cvMoments(imgYellowThresh, moments, 1);   // The actual moment values double moment10 = cvGetSpatialMoment(moments, 1, 0); double moment01 = cvGetSpatialMoment(moments, 0, 1); double area = cvGetSpatialMoment(moments, 0, 0);

// 计算重心

posX = moment10 / area;

posY = moment01 / area;

转自:http://blog.163.com/forever_871226/blog/static/34424308201141851736984/

/** 计算二值图像的重心

* @param[in] src  输入的待处理图像

* @param[out] center 重心坐标

* @retval 0  操作成功

* @retval -1 操作失败

* @note 输入图像是二值化图像

* @note xc=M10/M00, yc=M01/M00, 其中 Mx_order,y_order=SUMx,y(I(x,y)*x^x_order*y^y_order)

*/

static int aoiGravityCenter(IplImage *src, CvPoint &center)

{

//if(!src)

// return GRAVITYCENTER__SRC_IS_NULL;

double m00, m10, m01;

CvMoments moment;

cvMoments( src, &moment, 1);

m00 = cvGetSpatialMoment( &moment, 0, 0 );

if( m00 == 0)

return 1;

m10 = cvGetSpatialMoment( &moment, 1, 0 );

m01 = cvGetSpatialMoment( &moment, 0, 1 );

center.x = (int) (m10/m00);

center.y = (int) (m01/m00);

return 0;

}

转自:http://www.opencv.org.cn/forum/viewtopic.php?p=1016

#include "cv.h"

#include "highgui.h"

void main( int argc, char** argv )

{

IplImage* src;

CvMoments moments;

CvMat *region;

CvPoint pt1,pt2;

double m00 = 0, m10, m01, mu20, mu11, mu02, inv_m00;

double a, b, c;

int xc, yc;

// 第一条命令行参数确定了图像的文件名。

if( (src=cvLoadImage("two.bmp", 0))!= 0)

//if( (src=cvLoadImage("fbb.jpg", 0))!= 0)

//if( argc == 2 && (src=cvLoadImage(argv[1], 0))!= 0)

{

IplImage* dst = cvCreateImage( cvGetSize(src), 8, 3 );

CvMemStorage* storage = cvCreateMemStorage(0);

CvSeq* contour = 0;

cvThreshold( src, src, 100, 255, CV_THRESH_BINARY );//100 is the thredhold

cvNot( src, src );

cvNamedWindow( "Source", 1 );

cvShowImage( "Source", src );

//cvFindContours( src, storage, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0) );

cvFindContours( src, storage, &contour, sizeof(CvContour),CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );

cvZero( dst );

for( ; contour != 0; contour = contour->h_next )

{

//CvScalar color = CV_RGB( rand()&255, rand()&255, rand()&255 );

CvScalar color = CV_RGB( 255, 0,0 );

/* 用1替代 CV_FILLED 所指示的轮廓外形 */

cvDrawContours( dst, contour, color, color, -1, CV_FILLED, 8,cvPoint(0,0) );//you can change 1 to CV_FILLED

contour = cvApproxPoly( contour, sizeof(CvContour), storage, CV_POLY_APPROX_DP, 3, 1 );

//CvRect* r = (CvRect*)cvGetSeqElem( contour,1);

region=(CvMat*)contour;

cvMoments( region, &moments,0 );

//cvMoments( &contour, &moments,0 );

// cvDrawContours( cnt_img, _contours, CV_RGB(255,0,0), CV_RGB(0,255,0), _levels, 3, CV_AA, cvPoint(0,0) ); CV_FILLED

////////////////////////////////////////////////

/////////////////////////////////////////////////

m00 = moments.m00;

m10 = moments.m10;

m01 = moments.m01;

mu11 = moments.mu11;

mu20 = moments.mu20;

mu02 = moments.mu02;

//if( fabs(m00) < DBL_EPSILON )break;

inv_m00 = 1. / m00;

xc = cvRound( m10 * inv_m00 );

yc = cvRound( m01 * inv_m00 );

a = mu20 * inv_m00;

b = mu11 * inv_m00;

c = mu02 * inv_m00;

/////////////////

pt1.x=xc-1;pt1.y=yc;

pt2.x=xc+1;pt2.y=yc;

cvLine( dst, pt1, pt2, CV_RGB(0,255,0), 2, CV_AA, 0 );

pt1.x=xc;pt1.y=yc-1;

pt2.x=xc;pt2.y=yc+1;

cvLine( dst, pt1, pt2, CV_RGB(0,255,0), 2, CV_AA, 0 );

}

cvNamedWindow( "Components", 1 );

cvShowImage( "Components", dst );

cvWaitKey(0);

}

}

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

原文地址:https://www.cnblogs.com/xkiwnchwhd/p/10316023.html

时间: 2024-09-28 16:39:56

利用OpenCV求取图像的重心的相关文章

poj 1655 树形dp求取树的重心

http://poj.org/problem?id=1655 Description Consider a tree T with N (1 <= N <= 20,000) nodes numbered 1...N. Deleting any node from the tree yields a forest: a collection of one or more trees. Define the balance of a node to be the size of the large

OpenCV求取轮廓线

// Threshold.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <cv.h> #include <highgui.h> int g_threshold = 100; IplImage* img1= NULL; IplImage* g_gray = NULL; CvMemStorage* g_storage = NULL;

利用cvFindExtrinsicCameraParams2求取相机外参数

cvFindExtrinsicCameraParams2函数的定义: 1 void cvFindExtrinsicCameraParams2( const CvMat* object_points, 2 const CvMat* image_points, 3 const CvMat* intrinsic_matrix, 4 const CvMat* distortion_coeffs, 5 CvMat* rotation_vector, 6 CvMat* translation_vector

在python3下使用OpenCV 抓取摄像头图像并实时显示3色直方图

以下代码为在Python3环境下利用OpenCV 抓取摄像头的实时图像, 通过OpenCV的 calHist函数计算直方图, 并显示在3个不同窗口中. import cv2 import numpy as np from matplotlib import pyplot as plt import time cap  = cv2.VideoCapture(0) for i in range(0, 19):     print(cap.get(i)) while(1):     ret, fram

利用FreeImage将gif图像转为opencv中的Mat

网上有将gif转为iplimg的版本,只是用惯了C++的接口,所以就写了个转Mat的版本,代码比较简单 一.读文件 1 int MatFun::gif2Mat(char* data, size_t dataSize, vector<Mat>& gifImgs, Mat& singleImg) 2 { 3 /* initialise 4 ->open memory 5 ->getImageType 6 ->load bitmaps 7 ->bitmaps

使用JavaCV/OpenCV抓取并存储摄像头图像

http://blog.csdn.net/ljsspace/article/details/6702178  分类: 图形图像(3)  版权声明:本文为博主原创文章,未经博主允许不得转载. 本程序通过JFrame实时显示本机摄像头图像,并将图像存储到一个缓冲区,当用户用鼠标点击JFrame中任何区域时,显示抓取图像的简单动画,同时保存缓冲区的图像到磁盘文件中.点击JFrame关闭按钮可以退出程序. 实现: [java] view plain copy import java.awt.Graphi

利用OpenCV实现旋转文本图像矫正的原理及OpenCV代码

对图像进行旋转矫正,关键是要获取旋转角度是多少!获取了旋转角度就可以用仿射变换对图像进行矫正,图像旋转的代码可以参考我的博文http://blog.csdn.net/wenhao_ir/article/details/51469085 旋转角度怎么获取?可以对图像作傅里叶变换获取这个角度,具体怎么求,请听我慢慢道来! 文本图像的明显特征就是存在分行间隔,那么行与文字之间这个灰度值变化就不如真正的文字及文字间的变化剧烈,那么相应的这些地方的频谱值也低,即频谱的低谱部分,因为傅里叶变换就是表征图像各

求取圆形区域内的平均灰度值

#include <cmath> #include <opencv2/opencv.hpp> using namespace cv; using namespace std; const int kvalue = 15;//双边滤波邻域大小 const double PI = 3.14;//圆周率 int graylevel(Mat image, Mat dst, Point cen, int r)//求取圆形区域内的平均灰度值 { int graysum = 0, n = 0;

Java基于opencv—透视变换矫正图像

很多时候我们拍摄的照片都会产生一点畸变的,就像下面的这张图 虽然不是很明显,但还是有一点畸变的,而我们要做的就是把它变成下面的这张图 效果看起来并不是很好,主要是四个顶点找的不准确,会有一些偏差,而且矫正后产生的目标图是倒着的,哪位好心人给说说为啥 因为我也没有测试畸变很大的图像,也不能保证方法适用于每个图像,这里仅提供我的思路供大家参考. 思路: 我们最重要的就是找到图像的四个顶点,有利用hough直线,求直线交点确定四个顶点,有采用寻找轮廓确定四个顶点等等:今天我提供的思路,也是采用寻找轮廓