C++ OpenCV读取图片并遍历像素详解
详细讲解如何使用C++和OpenCV库实现图片读取、窗口显示,以及如何通过矩阵接口按行列访问图像底层的像素数据。包含完整的可运行代码示例。
核心功能说明
该示例代码演示了C++环境下基于OpenCV的图像处理基础操作:从磁盘加载图像到内存矩阵(Mat),验证图像有效性,实时渲染至GUI窗口,以及逐像素提取RGB/HSV等通道的原始数值。
准备条件
确保开发环境已正确安装OpenCV C++ SDK,且编译器支持C++11及以上标准(代码中使用了nullptr关键字)。准备一张测试图片,将其放置在项目源码所在的同级目录下,命名为1.jpg。
第1步:引入依赖并设置命名空间
目的:启用OpenCV的核心和高gui模块,简化后续函数调用。 操作:包含必要的头文件并使用using namespace cv;。 参数:无需额外参数。
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
第2步:初始化并加载图像
目的:将物理图片转化为可处理的内存结构。 入口:main函数主体。 动作:声明cv::Mat image;,调用imread函数指定相对路径。关键参数:"./1.jpg"(表示当前目录下的jpg文件)。 完成状态:image对象被初始化。
int main(int argc, char** argv)
{
Mat image;
image = imread("./1.jpg");
第3步:执行有效性校验
目的:防止因图片丢失或路径错误导致的空指针异常。 动作:判断image.data是否为nullptr(C++11特性)。若为空则输出错误信息。 重要参数:无。完成状态:确认非空后即可继续。
if (image.data == nullptr)
{
cout << "图片文件不存在" << endl;
} else {
第4步:展示图像窗口
目的:可视化验证读取成功。 动作:调用imshow创建标题为meinv的窗口并渲染图像。动作:随后调用waitKey(0)阻塞程序,直到用户按键,避免窗口闪退。 参数:"meinv"是窗口标题;0表示无限期等待按键。
imshow("meinv", image);
waitKey(0);
第5步:打印基本图像元数据
目的:获取并打印图像的几何特征。 入口:校验通过后的else分支内部。 动作:使用image.cols获取宽度,image.rows获取高度,image.channels()获取通道数(如彩色图为3)。 完成状态:控制台输出具体数值。
cout << "图像宽为:" << image.cols << "\t高度为:" << image.rows << "\t通道数为:" << image.channels() << endl;
第6步:遍历并解析像素点
目的:演示如何直接操作底层内存数据进行算法开发。 入口:在元数据打印之后。 动作:定义外层循环迭代每一行y,内层循环迭代每一列x。参数:使用size_t作为索引类型以防溢出。逻辑:通过image.ptr<unsigned char>(y)获取当前行的首地址。计算当前像素首地址公式:&row_ptr[x * channels]。再嵌套循环分别输出各通道的整型值。
// 遍历每个像素
for (size_t y = 0; y < image.rows; y++)
{
unsigned char* row_ptr = image.ptr<unsigned char>(y);
for (size_t x = 0; x < image.cols; ++x) {
// 获取单个像素的首地址指针
unsigned char* data_ptr = &row_ptr[x * image.channels()];
// 逐通道输出像素值
for (int i = 0; i < image.channels(); ++i) {
cout << int(data_ptr[i])<<endl;
}
}
}
完整参考代码
以下为整合上述步骤的完整工程代码,可直接用于编译测试:
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
Mat image;
image = imread("./1.jpg");
if (image.data == nullptr)
{
cout << "图片文件不存在" << endl;
}
else
{
//显示图片
imshow("meinv", image);
waitKey(0);
// 输出图片的基本信息
cout << "图像宽为:" << image.cols << "\t高度为:" << image.rows << "\t通道数为:" << image.channels() << endl;
// 遍历每个像素
for (size_t y = 0; y < image.rows; y++)
{
unsigned char* row_ptr = image.ptr<unsigned char>(y);
for (size_t x = 0; x < image.cols; ++x) {
unsigned char* data_ptr = &row_ptr[x * image.channels()];
for (int i = 0; i < image.channels(); ++i) {
cout << int(data_ptr[i])<<endl;
}
}
}
}
system("pause");
return 0;
}
实际输出效果
执行上述代码后,控制台会依次输出指定的图像尺寸、通道数以及海量的像素灰度/色彩值序列,同时弹出一个名为“meinv”的独立窗口承载图片展示。控制台部分输出截图如下:
排错提示
如果编译链接报错寻找不到cv相关的符号,通常是因为未配置Linker路径或未设置环境变量;若运行时提示无法打开图片,请检查.\
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













