opencv-利用PLSA算法自动从谷歌图片搜索学习颜色名称(ColorNaming)

颜色名称是人类对颜色的语言标签。比如以下11个色块我们进行语言标签




我们经常使用它们,来描述我们周围的世界,他们主要研究了视觉心理学、人类学和语言学等领域的研究。在计算机视觉上下文中的颜色命名是将语言颜色标签分配给图像像素的作用。利用机器学习算法自动从谷歌图片搜索学习颜色名称。

例如以下图片,

   

我们大体看到以下三种颜色:蓝色、绿色、橘色



Joost van de Weijer通过以下两篇文章:

Learning Color Names from Real-World Images 

Learning Color Names for Real-World Applications 

详细介绍了利用PLSA概率潜语义分析,从goole图片中学习了11种颜色,并给出了matlab代码。作者只给出了训练的结果。我用openCV复现了一遍。

-----------------------------------------------------------------------------------------------------------------------------------

我们只需要将BGR颜色空间,每一个通道的值0-255,每8个步长,进行分割,那么一共分为256/8=32个区间,因为有三个通道,那么一共给有32*32*32种组合。

opencv-代码:

#include<iostream>
using namespace std;

#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
using namespace cv;
Mat floorMat(const Mat & doubleMat);

int main(int argc,char * argv[])
{
	//读取图片
	Mat image = imread(argv[1],1);
	
	//判断是否有图片
	if(!image.data)
		return 0;
	
	//判断是否是彩色图片
	if( image.channels() != 3)
		return 0;

	int rows = image.rows;
	int cols = image.cols;
	int areas = rows*cols;
	
	//分离通道
	vector<Mat> bgr_planes;
	split(image,bgr_planes);

	//把各通道转为64F
	Mat bplanes,gplanes,rplanes;
	bgr_planes[0].convertTo(bplanes,CV_64FC1);
	bgr_planes[1].convertTo(gplanes,CV_64FC1);
	bgr_planes[2].convertTo(rplanes,CV_64FC1);
	
	//floor(各通道/8.0)
	Mat fbplanes,fgplanes,frplanes;
	fbplanes = floorMat(bplanes);
	fgplanes = floorMat(gplanes);
	frplanes = floorMat(rplanes);
	Mat index_im = frplanes+32*fgplanes+32*32*fbplanes;//index_im最大值可能为:31+31*32+32*32*31=32767

	Mat index_im_col;
	index_im_col = index_im.reshape(1,areas);

	//读取w2cM
	FileStorage fs(argv[2],FileStorage::READ);
	Mat w2cM;
	fs["w2cM"]>>w2cM;
	cout << "12"<<endl;
	//index_col存放的0-10之间的数值,代表11种颜色
	Mat index_col(areas,1,CV_32SC1);
	int tempIndex;
	for(int r = 0;r< areas;r++)
	{
		tempIndex = index_im_col.at<int>(r,0);
		index_col.at<int>(r,0) = w2cM.at<int>(tempIndex,0);
	}
	
	//reshape
	Mat out2 = index_col.reshape(1,rows);
	
	/* ----------------------11种颜色值----------------------------------*/
	Mat color_values(11,1,CV_64FC3);

	//black-黑色 [0 0 0]
	color_values.at<Vec3d>(0,0) = Vec3d(0,0,0);

	//blue-蓝色 [1 0 0]
	color_values.at<Vec3d>(1,0) = Vec3d(1,0,0);

	//brown-棕色(褐色) [0.25 0.4 0.5]
	color_values.at<Vec3d>(2,0) = Vec3d(0.25,0.4,0.5);

	//grey-灰色[0.5 0.5 0.5]
	color_values.at<Vec3d>(3,0) = Vec3d(0.5,0.5,0.5);

	//green-绿色[0 1 0]
	color_values.at<Vec3d>(4,0) = Vec3d(0,1,0);

	//orange-橘色[0 0.8 1]
	color_values.at<Vec3d>(5,0) = Vec3d(0,0.8,1);

	//pink-粉红色[1 0.5 1]
	color_values.at<Vec3d>(6,0) = Vec3d(1,0.5,1);

	//purple-紫色[1 0 1]
	color_values.at<Vec3d>(7,0) = Vec3d(1,0,1);

	//red-红色 [0 0 1]
	color_values.at<Vec3d>(8,0) = Vec3d(0,0,1);

	//white-白色 [1 1 1]
	color_values.at<Vec3d>(9,0) = Vec3d(1,1,1);

	//yellow-黄色[0 1 1]
	color_values.at<Vec3d>(10,0) = Vec3d(0,1,1);

	/*--------------------------------------------------------*/
	Mat out(rows,cols,CV_64FC3);
	for(int r = 0 ;r<rows;r++)
	{
		for(int c =0;c<cols;c++)
		{
			int tindex = out2.at<int>(r,c);
			out.at<Vec3d>(r,c) = color_values.at<Vec3d>(tindex,0)*255;
		}
	}
	Mat colorMap;
	out.convertTo(colorMap,CV_8UC3);
	namedWindow("colorMap",1);
	imshow("colorMap",colorMap);
	
	//关闭文件
	fs.release();
	
	waitKey(0);
	return 0;
}

//注意参数只为 CV_64FC1
Mat floorMat(const Mat & doubleMat)
{
	int rows = doubleMat.rows;
	int cols = doubleMat.cols;
	Mat flo(rows,cols,CV_32SC1);

	for(int r = 0;r < rows;r++)
	{
		for(int c = 0;c < cols ;c++)
		{
			flo.at<int>(r,c)= floor(doubleMat.at<double>(r,c)/8.0);
		}
	}
	return flo;
}

已经将w2c.mat转换为w2c.xml文件,下载地址:

【运行结果显示】:

                                             

上述图片进行颜色标签的结果为:

【黄色】【黑色】【橘色】

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

该算法可以用于基于颜色的图像检索、识别、运动物体跟踪等。。基于颜色识别我们可以用HLS、HSV颜色空间进行分割,也会有不错的效果,下一篇再写。

  • 9
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 22
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值