C++下OpenCV学习笔记----访问图像中的像素

C++下OpenCV学习笔记

----访问图像中的像素

文章目录

    • C++下OpenCV学习笔记
          • 一.像素的储存方式
          • 二.颜色空间缩减(color space reduction)
          • 三.LUT函数:look up table操作
          • 四.计时函数
          • 五.访问图像像素的三种方法

一.像素的储存方式
  1. 图像矩阵的大小取决于所用的颜色模型,进一步地说,取决于所用的通道数。
  2. OpenCV中子列的通道顺序为BGR。
  3. 判断矩阵是否连续储存:isContinuous( )函数
    (1)连续存储是返回true,否则返回false。
    (2)Mat的数据部分存储是按照行进行存储的,相同行内的数据是连续存储,行与行之间的存储是否有间隙,可以通过isContinuous函数来判断。对于1*1或1*N矩阵总是连续的,一般使用Mat::create创建的矩阵总是连续的,而如果使用Mat::col,Mat::diag等提取的矩阵一部分,或者外部分配的数据构造矩阵头,则此类矩阵可能不再连续存储。
    (3)代码实现
#include
#include
using namespace cv;
using namespace std;
int main()
{
	Mat src = imread("C:\\Users\\441\\Desktop\\ZL\\夏目\\1.jpg");
	cout << "Is continuous?       ";
	if (src.isContinuous())
		cout << "YES." << endl;
	else
		cout << "NO." << endl;
	Mat src1(src, Rect(250, 125, 250, 150));
	cout << "Is continuous?       ";
	if (src1.isContinuous())
		cout << "YES." << endl;
	else
		cout << "NO." << endl;
	return 0;
}

        (4)运行结果
在这里插入图片描述

二.颜色空间缩减(color space reduction)
  1. 定义:将现有颜色空间值除以某个输入值,以获得较少的颜色数。即做减法,比如颜色值0到9可取为新值0, 10到19可取为10,以此类推。
  2. 意义:可大大降低运算的复杂度。
  3. 简单的算法组成:
    (1)遍历图像矩阵的每一个像素
    (2)对像素运用缩减公式
  4. 代码实现(主函数)
#include
#include
using namespace cv;
using namespace std;
void colorReduce(Mat& inputImage, Mat& outputImage, int div)

int main()
{
	Mat src = imread("C:\\Users\\441\\Desktop\\ZL\\夏目\\1.jpg");
	imshow("原始图像",src);
	Mat dst;
	dst.create(src.rows, src.cols, src.type());
	double time = static_cast<double>(getTickCount());
	colorReduce(src, dst, 128);  //缩减128倍
	time = ((double)getTickCount() - time) / getTickFrequency();
	cout << "运行时间为:" << time << "秒." << endl;
	imshow("效果图", dst);
	waitKey(0);
	return 0;
}
  1. 运行结果
    C++下OpenCV学习笔记----访问图像中的像素_第1张图片

-->采用动态地址计算方法

void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{
	outputImage = inputImage.clone();
	int rowNumber = outputImage.rows;
	int colNumber = outputImage.cols;
	for (int i = 0;i < rowNumber;i++)
	{
		for (int j = 0; j < colNumber;j++)
		{
			outputImage.at<Vec3b>(i, j)[0] = outputImage.at<Vec3b>(i, j)[0] / div * div + div / 2;    //蓝色通道
			outputImage.at<Vec3b>(i, j)[1] = outputImage.at<Vec3b>(i, j)[1] / div * div + div / 2;    //绿色通道
			outputImage.at<Vec3b>(i, j)[2] = outputImage.at<Vec3b>(i, j)[2] / div * div + div / 2;    //红色通道
		}
	}
}

在这里插入图片描述
C++下OpenCV学习笔记----访问图像中的像素_第2张图片
-->采用迭代器方法

void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{
	outputImage = inputImage.clone();    //复制实参到临时变量
	Mat_<Vec3b>::iterator it = outputImage.begin<Vec3b>();    //初始位置的迭代器
	Mat_<Vec3b>::iterator itend = outputImage.end<Vec3b>();    //终止位置的迭代器
    //存取彩色图像像素
	for (;it != itend;++it)
	{
		(*it)[0] = (*it)[0] / div * div + div / 2;
		(*it)[1] = (*it)[1] / div * div + div / 2;
		(*it)[2] = (*it)[1] / div * div + div / 2;
	}
}

在这里插入图片描述
C++下OpenCV学习笔记----访问图像中的像素_第3张图片
-->采用指针计算方法

void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{
	outputImage = inputImage.clone();    //复制实参到临时变量
	int rowNumber = outputImage.rows;    //行数
	int colNumber = outputImage.cols * outputImage.channels();    //列数x通道数=每一行元素的个数
	//双重循环,遍历所有的像素值
	for (int i = 0; i < rowNumber;i++)    //行循环
	{
		uchar* data = outputImage.ptr<uchar>(i);    //获取第i行的首地址
		for (int j = 0;j < colNumber;j++)    //列循环
			data[j] = (data[j] / div) * div + div / 2;   //开始处理每个像素
	}
}

在这里插入图片描述
C++下OpenCV学习笔记----访问图像中的像素_第4张图片

三.LUT函数:look up table操作
  1. 定义
    void LUT(InputArray src, InputArray lut, OutputArray dst,int interpolation);

第一个参数:表示输入的图像
第二个参数:表示查找表(查找表也可以是单通道,也可以是3通道,如果输入图像为单通道,那查找表必须为单通道;若输入图像为3通道,查找表可以为单通道,也可以为3通道,若为单通道则表示对图像3个通道都应用这个表,若为3通道则分别应用 )
第三个参数:表示插值,默认为0

  1. 代码实现
    单通道
#include
using namespace cv;
int main()
{
    uchar lutData[256];
    for (int i = 0; i < 256; i++)
    {
        if (i <= 100)
            lutData[i] = 0;
        if (i > 100 && i <= 200)
            lutData[i] = 100;
        if (i > 200)
            lutData[i] = 200;
    }
    Mat lut(1, 256, CV_8UC1, lutData);
    Mat src = imread("C:\\Users\\441\\Desktop\\ZL\\夏目\\1.jpg");
    Mat dst;

    imshow("原始图像", src);
    LUT(src, lut, dst);
    imwrite("dst.jpg", dst);
    imshow("效果图", dst);
    waitKey(0);
}

三通道

#include
using namespace cv;
int main()
{
	uchar lutData[256 * 3];
	for (int i = 0; i < 256; i++)
	{
		if (i <= 100)
		{
			lutData[i * 3] = 0;
			lutData[i * 3 + 1] = 100;
			lutData[i * 3 + 2] = 200;
		}
		if (i > 100 && i <= 200)
		{
			lutData[i * 3] = 100;
			lutData[i * 3 + 1] = 200;
			lutData[i * 3 + 2] = 0;
		}
		if (i > 200)
		{
			lutData[i * 3] = 200;
			lutData[i * 3 + 1] = 0;
			lutData[i * 3 + 2] = 100;
		}
	}
	Mat lut(1, 256, CV_8UC3, lutData);
    Mat src = imread("C:\\Users\\441\\Desktop\\ZL\\夏目\\1.jpg");
    Mat dst;

    imshow("原始图像", src);
    LUT(src, lut, dst);
    imwrite("dst.jpg", dst);
    imshow("效果图", dst);
    waitKey(0);
}
  1. 运行结果
    C++下OpenCV学习笔记----访问图像中的像素_第5张图片
    单通道
    C++下OpenCV学习笔记----访问图像中的像素_第6张图片
    三通道
    C++下OpenCV学习笔记----访问图像中的像素_第7张图片
四.计时函数
  1. 定义
    getTickCount( )函数返回CPU自某个事件以来走过的时钟周期数
    getTickFrequency( )函数返回CPU一秒钟所走的时钟周期数。

  2. 主要代码

double time0 = static_cast<double>(getTickCount());   //记录起始时间
...   //图像操作
time0 = ((double)getTickCount() - time0) / getTickFrequency();
cout << "运行时间为:" << time0 << "秒." << endl;
五.访问图像像素的三种方法

---->亮度和对比度中访问图像像素的方法

  1. 动态地址计算
  2. 用迭代器操作像素
  3. 用指针访问像素

(见第二点)

你可能感兴趣的:(opencv,opencv,计算机视觉,c++)