图像处理中很多时候会对像素点进行操作。在OpenCV有许多方法来对像素进行遍历。

at()函数

对于单通道图像"picture1",picture1.at<uchar>(i,j)就表示在第i行第j列的像素值。

对于多通道图像如RGB图像"picture2",可以用picture2.at<Vec3b>(i,j)[c]来表示某个通道中在(i,j)位置的像素值。

1)上面的uchar、Vec3b表示图像元素的类型。

2)(i,j)当然就是指像素点的位置,表示第i行第j列。

3)[c]表示的是通道,对于RGB图像而言,c取0就是B分量;c取1就是G分量;c取2就是R分量(要注意在OpenCV中是按BGR的顺序表示的)。

在OpenCV官方文档中是这么写的:

翻译

 注意:

我们有时候回遇到这种情况

带有单个索引(i)的变量可用于访问单行或单列二维数组的元素。也就是说,如果,例如,A是一个1 x N的浮点矩阵,B是一个M x 1的整数矩阵,你可以简单地写A在<float>(k+4)处和B在<int>(2*i+1)处,而不是A在<float>(0,k+4)处和B在<int>(2*i+1,0)处。

例如:

double predictAngle = prediction.at<float>(0); 

上面代码的意思就是,prediction是个单行或者单列的单通道Mat类型,prediction.at<float>(0)即为访问数组的第一个元素(可以理解为访问一个一维数组的第一个元素)

但是我发现

不是单行或者单列的Mat类型(但需要为单通道)也可以使用at<float>(n),这种情况下会默认访问矩阵第一行(row =0)的元素,以第一行来进行索引。

即double predictAngle = prediction.at<float>(4);  等价于:double predictAngle = prediction.at<float>(0,4);

/**
 *Copyright (c) 2019 Young Fan.All Right Reserved.
 *Author: Young Fan
 *Date: 2019.05.16
 *IDE: Visual Studio 2017
 *Description:
 */

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


int main()
{
	Mat img = imread("1.jpg", 0); //以单通道读入图片
	int x = img.at<uchar>(118);
	int y = img.at<uchar>(0,118);
	cout << x << endl;
	cout << y << endl;
	imshow("图像", img);

	waitKey();
	

	return 0;
}

 

代码

下面对像素的操作,使用的是动态地址计算方式。操作像素的方式还有其他两种:C语言指针访问像素迭代器操作像素。

单通道图像遍历:


#include <opencv2/opencv.hpp>

using namespace cv;

 

int main(int argc, char** argv)

{

	Mat picture(200, 200, CV_8UC1);/*创建图像picture,默认为纯黑色(即每个点的像素值为0),

								   大小为200 * 200,类型为CV_8UC1(是单通道图像)*/

 

	imshow("picture", picture);	//在“picture”窗口显示图像picture

 

	//遍历picture的每个像素点,并将所有像素点的值修改为150

	for (int i = 0; i < 200; i++)

	{

		for (int j = 0; j < 200; j++)

			picture.at<uchar>(i, j) = 150;

	}

 

	imshow("dst", picture);//在“dst”窗口显示修改后的图像picture

	waitKey(0);//等待用户按键

	return 0;

}

运行结果:

彩色图像遍历:


#include <opencv2/opencv.hpp>

using namespace cv;

 

int main(int argc, char** argv)

{

	Mat picture(200, 200, CV_8UC3);//新建一个三通道彩色图像,初始默认为纯黑色

	imshow("picture", picture);	

 

	//遍历picture的每个像素点,并将每个通道所有像素点的值修改为0~255中随机一个整数值

	for (int i = 0; i < 200; i++)

	{

		for (int j = 0; j < 200; j++)

		{

			picture.at<Vec3b>(i, j)[0] = rand() % 255;//B通道

			picture.at<Vec3b>(i, j)[1] = rand() % 255;//G通道

			picture.at<Vec3b>(i, j)[2] = rand() % 255;//R通道

		}

	}

 

	imshow("dst", picture);

	waitKey(0);

	return 0;

}

运行效果:

参考:

https://blog.csdn.net/qq_36503007/article/details/79895610

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐