Opencv学习笔记(三)降低颜色空间

原创 2018年04月15日 23:11:57

  首先认识一下简单的色彩降低方法(color reduction method),如果使用的是c或c++无符号的char(八字节大小的空间),一个信道(channel)有256个不同的值(2^8=256),但是如果使用的是GRB方案,三个channel的话,颜色的数量就会变为256*256*256,大概是16个million这么多,这么多的颜色数量,对于计算机来说仍然是一个负担,所以可以想一些方法来降低这些色彩数量。

  假定图片色度范围为0-255,N选取为64,则色彩数降低为4X4X4;换算公式为data=data/N*N+N/2;data/N获得色度区间0-64->064-128->164-128->1,128-192->2,128-256->3再乘以N,为0、64、128、192, 再加N/2 ,从0-255变为4个色度32、96、160、224,即变为每个范围内的中值。实例代码如下:

#include <iostream>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;


void colorReduce(Mat& srcImg, Mat& dstImg, int n)
{
	double start = static_cast<double>(getTickCount());
	for (int i = 0; i < dstImg.rows; i++)
	{
		for (int j = 0; j < dstImg.cols; j++)
		{
				dstImg.at<Vec3b>(i, j)[0] = (srcImg.at<Vec3b>(i, j)[0] / n) * n + n / 2; //将色度降低n倍
				dstImg.at<Vec3b>(i, j)[1] = (srcImg.at<Vec3b>(i, j)[1] / n) * n + n / 2;
				dstImg.at<Vec3b>(i, j)[2] = (srcImg.at<Vec3b>(i, j)[2] / n) * n + n / 2;
		}
	}
	double end = static_cast<double>(getTickCount());
	double time = (end - start) / getTickFrequency();
	cout << "运行时间为:" << time << "秒" << endl;
	imshow("原图像", srcImg);
	imshow("阈值处理后图像", dstImg);
	waitKey(0);

}

void colorReduceByPointer0(Mat& srcImg, Mat& dstImg, int n)
{
	double start = static_cast<double>(getTickCount());
	int row = dstImg.rows;
	int col = dstImg.cols * dstImg.channels();
	for (int i = 0; i < row; i++)
	{
		uchar* data = dstImg.ptr(i);	//	获取每行首地址
		for (int j = 0; j < col; j++)
		{
			data[j] = (data[j] / n) * n + n / 2;    //将色度降低n倍
		}
	}
	double end = static_cast<double>(getTickCount());
	double time = (end - start) / getTickFrequency();
	cout << "运行时间为:" << time << "秒" << endl;
	imshow("原图像", srcImg);
	imshow("阈值处理后的图像", dstImg);
	waitKey(0);
}

void colorReduceByPointer1(Mat& srcImg, Mat& dstImg, int n)
{
	double start = static_cast<double>(getTickCount());
	int row = dstImg.rows;
	int col = dstImg.cols * dstImg.channels();
	for (int i = 0; i < row; i++)
	{
		uchar* data = dstImg.ptr(i);
		for (int j = 0; j < col; j++)
		{
			data[j] = (data[j] / n) * n + n / 2;
		}
	}
	double end = static_cast<double>(getTickCount());
	double time = (end - start) / getTickFrequency();
	cout << "运行时间为:" << time << "秒" << endl;
	imshow("原图像:", srcImg);
	imshow("阈值处理后的图像", dstImg);
	waitKey(0);
}

void colorReduceByInterator0(Mat& srcImg, Mat& dstImg, int n)
{
	double start = static_cast<double>(getTickCount());
	Mat_<uchar>::iterator it = dstImg.begin<uchar>();
	Mat_<uchar>::iterator itend = dstImg.end<uchar>();
	for (; it != itend; it++)
	{
		*it = (*it / n ) * n + n/2;
	}
	double end = static_cast<double>(getTickCount());
	double time = (end - start) / getTickFrequency();
	cout << "运行时间为:" << time << "秒" << endl;
	imshow("原图像:", srcImg);
	imshow("阈值处理后的图像", dstImg);
	waitKey(0);
}

void colorReduceByInterator1(Mat& srcImg, Mat& dstImg, int n)
{
	double start = static_cast<double>(getTickCount());
	Mat_<Vec3b>::iterator it = dstImg.begin<Vec3b>();
	Mat_<Vec3b>::iterator itend = dstImg.end<Vec3b>();
	for (; it != itend; it++)
	{
		(*it)[0] = ((*it)[0] / n)*n + n / 2;
		(*it)[1] = ((*it)[1] / n)*n + n / 2;
		(*it)[2] = ((*it)[2] / n)*n + n / 2;

	}
	double end = static_cast<double>(getTickCount());
	double time = (end - start) / getTickFrequency();
	cout << "时间:" << time << "秒" << endl;
	imshow("原图像", srcImg);
	imshow("阈值处理后的图像", dstImg);
	waitKey(0);

}


int main(int argc, char* argv[])
{
	Mat GrayOutImg, ColorOutImg, GrayImg, ColorImg;
	GrayImg = imread("D:\\1.png", 0);
	GrayOutImg = GrayImg.clone();
	ColorImg = imread("D:\\1.png", 1);
	ColorOutImg = ColorImg.clone();

	//colorReduce(ColorImg, ColorOutImg, 32);			//0
	//colorReduceByInterator0(GrayImg, GrayOutImg, 32);		//1
	colorReduceByInterator1(ColorImg, ColorOutImg, 32);		//2
	//colorReduceByPointer0(InImg, GrayOutImg, 32);		        //3
	//colorReduceByPointer1(ColorImg, ColorOutImg, 32);		//4

	return 0;
}

opencv学习笔记---hsv颜色空间

1. RGB模型。 三维坐标: 原点到白色顶点的中轴线是灰度线,r、g、b三分量相等,强度可以由三分量的向量表示。 用RGB来理解色彩、深浅、明暗变化: 色彩变化:...
  • dancing_night
  • dancing_night
  • 2016-05-23 10:58:32
  • 1653

【学习 OpenCV】—— 将一个3通道的像素点转换到新的彩色空间

将一个3通道的像素点,cv::Vec target,转换到新的彩色空间,比如 Lab 彩色空间。因为封装好的 api cv::cvtColor() 处理的对象是 cv::Mat 类型,所以我们有必要进...
  • lanchunhui
  • lanchunhui
  • 2016-04-16 12:21:00
  • 677

opencv图像颜色空间转换

opencv常用的样色空间包括RGB, HSV和YUV等。RGB颜色空间是基于三基色原理二形成的,常用于图像显示系统中;HSV描述的色度,饱和度,亮度这些表示颜色得方法,常用于描述色彩变化;YUV是通...
  • UESTC_C2_403
  • UESTC_C2_403
  • 2017-06-02 23:23:55
  • 1248

【OpenCV学习笔记】三、操作像素

最近在系统地学习OpenCV,将学习的过程在此做一个记录,主要以代码+注释的方式 记录学习过程。 1.访问像素值   要访问矩阵中的每个独立元素,只需要指定它的行号和列号。返回的对应元素可以是单个数...
  • abc8730866
  • abc8730866
  • 2017-02-19 21:00:23
  • 741

Opencv2中LUT函数操作(颜色空间缩减)

#include   #include   using namespace std;   using namespace cv;   int main( )   {   //建立一个查找表   i...
  • liyuqian199695
  • liyuqian199695
  • 2016-07-05 15:50:51
  • 916

OpenCV学习笔记(八)--颜色空间及转换

颜色空间要用三种或更多的特征来指定一种颜色,有许多的方法被称为颜色空间或者颜色模型。 如何选取其中一种方法来表示一副图像要依赖于执行的运算。 不同的颜色空间的转换,Opencv提供方法void...
  • taoyanqi8932
  • taoyanqi8932
  • 2016-09-25 21:43:12
  • 5402

OpenCv实现 颜色空间缩减

OpenCv实现 颜色空间缩减:                            http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/t...
  • liuxingwan
  • liuxingwan
  • 2015-09-24 17:23:22
  • 667

LAB颜色空间各通道的取值范围

简介LAB颜色空间在计算机视觉中经常被使用,知道L,A,B三个通道的取值范围有一定的意义。L∈[0, 100]A∈[−86.1813, 98.2352]B∈[−107.8618, 94.4758] L...
  • bendanban
  • bendanban
  • 2015-08-28 16:16:05
  • 4437

OpenCV学习(四)颜色空间缩减实现

在一幅数字图像存储的矩阵一般是uchar类型,为8位256个值。如果是三通道图形,那么应该有256*256*256=16581375种不同的颜色,这1600多万种颜色,数据量会很大,影响后期的处理,这...
  • u010886476
  • u010886476
  • 2016-07-17 11:08:57
  • 1474

五、颜色空间缩减

一、目的 如果采用3通道颜色空间,比如RGB(其在opencv中储存为BGR)。 如果一个元素采用unsigned char ,则有256个数值,3个元素则需要16777216...
  • u012235003
  • u012235003
  • 2017-05-04 19:14:46
  • 509
收藏助手
不良信息举报
您举报文章:Opencv学习笔记(三)降低颜色空间
举报原因:
原因补充:

(最多只允许输入30个字)