当前位置: 首页> 娱乐> 八卦 > 实战OpenCV之像素操作

实战OpenCV之像素操作

时间:2025/7/10 11:42:23来源:https://blog.csdn.net/hope_wisdom/article/details/142032604 浏览次数:1次

基础入门

        在OpenCV中,像素是最基本的操作单位。图像可以视为一个三维数组,其中第三维表示颜色通道。图像数据在内存中以连续或几乎连续的方式存储,对于多通道图像(比如:BGR图像),每个像素的各通道值紧密排列。OpenCV主要使用BGR色彩空间,与常用的RGB顺序不同。因此,在进行像素操作时,需要特别注意色彩通道的顺序。OpenCV中最常见的图像格式是CV_8UC3,表示一个8位无符号整型的三通道图像。

        像素操作通常会涉及到颜色,在OpenCV中,Scalar类型常用来表示颜色。一个Scalar对象可以存储四个元素,分别对应于图像中的四个通道,通常为BGRA色彩空间。当处理彩色图像时,这四个值代表蓝色(B)、绿色(G)、红色(R)和可选的透明度(A,alpha通道)。如果处理的是灰度图像,则通常只使用第一个通道即可。

        如果我们想定义一个红色的颜色,可以参考下面的示例代码。

// BGR格式,故(0, 0, 255)代表红色
cv::Scalar redColor(0, 0, 255);

        对于带有透明度的颜色,可以像下面的示例代码这样,定义一个半透明的红色。

// 最后一个值是alpha通道,范围从0(完全透明)到255(完全不透明)
cv::Scalar semiTransparentColor(0, 0, 255, 128);

实战解析

        在OpenCV中,主要有两种方式来访问和修改像素值:指针访问和at函数访问。

        指针访问是指直接通过计算像素地址来进行操作,这种方式在性能上可能更优,但实现较为复杂,容易出错。在下面的示例代码中,我们创建了一个300 x 400像素的蓝色图像,并通过指针访问方式将图像最中间一行的像素修改为红色。

#include <opencv2/opencv.hpp>
#include <iostream>using namespace cv;
using namespace std;int main()
{// 创建一个300 x 400的蓝色图像Mat img(300, 400, CV_8UC3, Scalar(255, 0, 0));// 访问并修改最中间一行的像素,将其变为红色int nMidRow = img.rows / 2;uchar* pRow = img.ptr<uchar>(nMidRow);for (int nCol = 0; nCol < img.cols; nCol++){// B分量pRow[nCol * 3] = 0;// G分量pRow[nCol * 3 + 1] = 0;// R分量pRow[nCol * 3 + 2] = 255;}// 显示图像imshow("Image", img);waitKey(0);return 0;
}

        at函数访问提供了一种更安全、更易读的方式来访问和修改像素值,虽然牺牲了一点性能,但代码更加清晰。在下面的示例代码中,我们同样创建了一个300 x 400像素的蓝色图像,并通过at函数访问方式将图像最中间一行的像素修改为红色。

#include <opencv2/opencv.hpp>
#include <iostream>using namespace cv;
using namespace std;int main()
{// 创建一个300 x 400的蓝色图像Mat img(300, 400, CV_8UC3, Scalar(255, 0, 0));// 访问并修改最中间一行的像素,将其变为红色int nMidRow = img.rows / 2;for (int nCol = 0; nCol < img.cols; nCol++){// 通过at函数访问每个像素并修改其颜色分量img.at<Vec3b>(nMidRow, nCol)[0] = 0;img.at<Vec3b>(nMidRow, nCol)[1] = 0;img.at<Vec3b>(nMidRow, nCol)[2] = 255;}// 显示图像imshow("Image", img);waitKey(0);return 0;
}

        执行上面的示例代码,运行效果可参考下图。

均值计算

        在OpenCV中,计算图像的像素均值,主要利用cv::mean()函数。像素均值被计算出来后,可以作为图像亮度调整的基础。

Mat img;
Scalar avgPixel = cv::mean(img);
cout << avgPixel[0] << ", " << avgPixel[1] << ", " << avgPixel[2] << endl;

像素级逻辑操作

        像素级逻辑操作通常涉及按位与、或、异或等操作,主要用于图像处理中的掩码应用、图像合成等场景。OpenCV提供了一系列函数来执行像素级的逻辑操作,下面逐一进行介绍。

        1、逻辑与。cv::bitwise_and()函数用于对两个图像的对应像素执行逻辑与操作。如果两个像素都为非零,结果像素就是非零;否则,结果像素为零。这对于应用掩码、选取图像的交集区域非常有用。

        2、逻辑或。cv::bitwise_or()函数用于对两个图像的对应像素执行逻辑或操作。只要两个像素中有一个为非零,结果像素就是非零。这可以用来合并图像的区域,或增加特征检测的鲁棒性。

        3、逻辑异或。cv::bitwise_xor()函数用于对两个图像的对应像素执行逻辑异或操作。当两个对应像素不同时,结果像素为非零;否则,结果像素为零。这可以用于突出显示两个图像之间的差异。

        4、逻辑非。cv::bitwise_not()函数用于对图像中的每个像素执行逻辑非操作,即将1变为0,0变为1。这常用于图像的反转,或颜色空间转换前的预处理。

        注意:在使用以上这些函数时,需要确保输入图像的数据类型兼容,并且大小相同。此外,还可以传入一个可选的掩码参数,仅对掩码中非零的像素执行操作,这对于局部处理非常有用。

        接下来,我们通过下面的实战代码来理解cv::bitwise_and()函数。

#include <opencv2/opencv.hpp>
#include <iostream>using namespace cv;
using namespace std;int main()
{Mat srcImage = imread("OpenCV.png");if(srcImage.empty()){cout << "Image not found" << endl;return -1;}// 创建一个矩形的掩码图像,初始化为全黑Mat mask = Mat::zeros(srcImage.size(), CV_8UC1);// 画一个白色矩形作为掩码rectangle(mask, Point(150, 0), Point(450, 250), Scalar(255, 255, 255), -1);// 使用bitwise_and函数应用掩码Mat destImage;bitwise_and(srcImage, srcImage, destImage, mask);// 显示原图、掩码和结果imshow("Original Image", srcImage);imshow("Mask", mask);imshow("Result Image", destImage);waitKey(0);destroyAllWindows();return 0;
}

        在上面的示例代码中,我们首先读取了一张图片到srcImage中。接着,我们创建了一个与原图同样大小的单通道灰度图像mask,并用一个白色矩形填充了其中一部分。这个白色矩形就是我们的“感兴趣区域”,其余部分为黑色,代表透明或不需要的部分。

        通过bitwise_and函数,我们将原图srcImage与自身进行了按位与操作,并且指定了掩码mask。这意味着只有掩码中为白色(值为255)的部分,在结果图像中保留了原图的像素值。而掩码中为黑色(值为0)的部分,在结果图像中对应的像素值将被设为0(黑色),从而达到了只显示我们感兴趣区域的效果。

        最后,我们使用imshow显示了原图、掩码、应用掩码后的结果图像,可参考如下。

关键字:实战OpenCV之像素操作

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: