颜色矩原理及C++实现
来源:互联网 发布:163邮箱注册软件 编辑:程序博客网 时间:2024/06/14 19:42
1 颜色矩原理
颜色矩(color moments)是由Stricker和Orengo[1]所提出的一种非常简单而有效的颜色特征。这种方法的数学基础在于图像中任何的颜色分布均可以用它的矩来表示。此外,由于颜色分布信息主要集中在低阶矩中,因此仅采用颜色的一阶矩(mean)、二阶矩(variance)和三阶矩(skewness)就足以表达图像的颜色分布。与颜色直方图相比,该方法的另一个好处在于无需对特征进行向量化。因此,图像的颜色矩一共只需要9个分量(3个颜色分量,每个分量上3个低阶矩),与其他的颜色特征相比是非常简洁的。在实际应用中为避免低次矩较弱的分辨能力,颜色矩常和其它特征结合使用,而且一般在使用其它特征前起到过滤缩小范围(narrow down)的作用。
三种颜色矩的数学定义:
其中,
- 一阶矩表示第i个颜色通道上所有像素的均值
- 二阶矩表示第i 颜色通道上所有像素的标准差
- 三阶矩表示第i个通道上所有像素的斜度(skewness)的三次方根。
图像的三个分量的前三阶颜色矩组成一个9维颜色特征向量。
2 颜色矩的C++实现
在网上找了很久也没有找到公开的用C++实现的颜色矩代码,OpenCV里面也没有现成的函数可以调用。因为项目需要,只能参考公式和其他版本(Matlab、Python)的颜色矩实现代码自己用C++写一个。但由于很久没用OpenCV了,写出来并调通还花了不少时间。本人水平有限,如有更好的C++实现代码希望交流学习。废话不多说,下面是颜色矩的C++实现(软件环境Windows10+VS2013+OpenCV2.4.9):
#include <iostream>#include <opencv2/opencv.hpp>using namespace std;using namespace cv;double calc3orderMom(Mat &channel) //计算三阶矩{ uchar *p; double mom=0; double m = mean(channel)[0]; //计算单通道图像的均值 int nRows = channel.rows; int nCols = channel.cols; if (channel.isContinuous()) //连续存储有助于提升图像扫描速度 { nCols *= nRows; nRows = 1; } for (int i = 0; i < nRows; i++) //计算立方和 { p = channel.ptr<uchar>(i); for (int j = 0; j < nCols; j++) mom += pow((p[j] - m) ,3); } float temp; temp = cvCbrt((float)(mom / (nRows*nCols))); //求均值的立方根 mom = (double)temp; return mom;}//计算9个颜色矩:3个通道的1、2、3阶矩double *colorMom(Mat &img){ double *Mom = new double[9]; //存放9个颜色矩 Mat hsvimg; if (img.channels() != 3) cout << "Error,input image must be a color image" << endl; Mat r(img.rows, img.cols, CV_8U); Mat g(img.rows, img.cols, CV_8U); Mat b(img.rows, img.cols, CV_8U); Mat channels[] = { b, g, r }; split(img, channels); Mat tmp_m, tmp_sd; //计算b通道的颜色矩 meanStdDev(b, tmp_m, tmp_sd); Mom[0] = tmp_m.at<double>(0, 0); Mom[3] = tmp_sd.at<double>(0, 0); Mom[6] = calc3orderMom(b);// cout << Mom[0] << " " << Mom[1] << " " << Mom[2] << " " << endl; //计算g通道的颜色矩 meanStdDev(g, tmp_m, tmp_sd); Mom[1] = tmp_m.at<double>(0, 0); Mom[4] = tmp_sd.at<double>(0, 0); Mom[7] = calc3orderMom(g);// cout << Mom[3] << " " << Mom[4] << " " << Mom[5] << " " << endl; //计算r通道的颜色矩 meanStdDev(r, tmp_m, tmp_sd); Mom[2] = tmp_m.at<double>(0, 0); Mom[5] = tmp_sd.at<double>(0, 0); Mom[8] = calc3orderMom(r);// cout << Mom[6] << " " << Mom[7] << " " << Mom[8] << " " << endl; return Mom;//返回颜色矩数组}//测试代码int main(){ Mat src = imread("purple.jpg"); if (src.data == NULL) cout << "image load failed!"; double *Mom ; Mom = colorMom(src); cout << "Color moments:"; for (int i = 0; i < 9; i++)//输出颜色矩 cout << Mom[i] << " "; cout << endl; waitKey();}
运行结果:
参考文献
1.stricker M ,Orengo M.similarity of col0rimages[J].Proc.SPIE St0rage and Retrieval f0r Image and Video Dtabases,1995,242O:381—392
2. 颜色特征提取(二)——颜色矩
3. 颜色矩原理及Python实现
- 颜色矩原理及C++实现
- CRC算法原理及C语言实现
- CRC算法原理及C语言实现
- C语言getbits函数原理及实现
- 堆排序原理及c语言实现
- UDP flood 原理及源码 C实现
- CRC算法原理及C语言实现
- C语言动态数组原理及实现
- Objective-C 通知(NSNotification)及实现原理
- [C++] MD5加密算法原理及实现
- [C/C++] 智能指针的实现及原理
- gamma原理及快速实现算法(C/C++)
- gamma原理及快速实现算法(C/C++)
- Fuzzy C-mean 聚类原理及图像颜色分割的实例
- CRC算法原理及C语言实现(一)
- CRC算法原理及C语言实现(转)
- 自动升级的原理及C#代码实现
- 堆排序原理简述及C实现实例
- maven:资源过滤的介绍
- RabbitMQ消息队列知识点归纳
- 用python创建桌面应用(二)
- SVN简单概述
- (ZT)clear icon cache
- 颜色矩原理及C++实现
- 集合框架-泛型接口的概述和使用
- Android 人品计算器
- 第三十九讲项目一 判断n是否是完数
- 电商秒杀系统设计分析
- PPTP源码流程分析图
- EL表达式中获取list长度
- Linux下SD卡驱动移植
- netBeans如何连接mysql