首页 > 其他分享 >实战OpenCV之像素操作

实战OpenCV之像素操作

时间:2024-09-12 09:54:20浏览次数:10  
标签:实战 img 像素 OpenCV nCol 图像 掩码 cv

基础入门

        在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显示了原图、掩码、应用掩码后的结果图像,可参考如下。

标签:实战,img,像素,OpenCV,nCol,图像,掩码,cv
From: https://blog.csdn.net/hope_wisdom/article/details/142032604

相关文章

  • 机器学习:opencv--图像金字塔
    目录一、图像金字塔1.图像金字塔是什么?2.有哪些常见类型?3.金字塔的构建过程4.图像金字塔的作用二、图像金字塔中的操作1.向下采样2.向上采样3.注意--无法复原三、代码实现1.高斯金字塔向下采样2.高斯金字塔向上采样3.无法复原4.拉普拉斯金字塔一、图像金字塔......
  • 实战05-Banner(Swiper)
    import{IBannerItem,IBannerList}from'../../api/models/HomeData';@ComponentexportdefaultstructSwiperLayout{@PropbannerList:IBannerList;build(){Swiper(){ForEach(this.bannerList,(banner:IBannerItem)=>{......
  • 《企业实战分享 · SonarQube10.x 详细教程》
    ......
  • 从注册到实战,超简单图床使用(附代码实现本地图片转换为网络url)
    1.注册一个薄荷图床的的账号,并添加客服申请api测试权限​ 查看api文档 我们只需关注两个必选参数即可,如图中红色标注2.编写pthon代码​ 其他语言也可以,只要发送post请求即可,注意url、token和照片需要更改为你自己的importrequestsdefpython_demo():url='https://......
  • 实战千问2大模型第三天——Qwen2-VL-7B(多模态)视频检测和批处理代码测试
    画面描述:这个视频中,一位穿着蓝色西装的女性站在室内,背景中可以看到一些装饰品和植物。她双手交叉放在身前,面带微笑,似乎在进行一场演讲或主持活动。她的服装整洁,显得非常专业和自信。一、简介阿里通义千问开源新一代视觉语言模型Qwen2-VL。其中,Qwen2-VL-72B在大部分指标上都......
  • OpenCV结构分析与形状描述符(19)查找二维点集的最小面积外接旋转矩形函数minAreaRect()
    操作系统:ubuntu22.04OpenCV版本:OpenCV4.9IDE:VisualStudioCode编程语言:C++11算法描述找到一个包围输入的二维点集的最小面积旋转矩形。该函数计算并返回指定点集的最小面积边界矩形(可能是旋转的)。开发者需要注意的是,当数据接近包含的Mat元素边界时,返回的Rotated......
  • OpenCV结构分析与形状描述符(20)计算一个包围给定点集的最小外接圆函数minEnclosingCirc
    操作系统:ubuntu22.04OpenCV版本:OpenCV4.9IDE:VisualStudioCode编程语言:C++11算法描述找到一个包围二维点集的最小面积的圆。该函数使用迭代算法来寻找一个二维点集的最小外接圆。这意味着函数将会通过反复逼近的过程来计算出能够包围所有给定点且面积最小的圆。mi......
  • 从数据洞察到智能决策:合合信息&infiniflow RAG技术的实战案例分享
    从数据洞察到智能决策:合合信息&infiniflowRAG技术的实战案例分享标题取自LLamaIndex,这个内容最早提出于今年2月份LlamaIndex官方博客。从22年chatGpt爆火,23年大模型尝鲜,到24年真正用AI落地业务场景,业界普遍都发现了从MVP到PMF不是那么容易的,具体的原因有非常......
  • 足球大小球及亚盘数据分析与机器学习实战详解:从数据清洗到模型优化
    本文将深入探讨Java在数据分析和机器学习中的实际应用,涵盖数据预处理、模型训练和优化等方面的内容。通过详尽的代码示例,帮助读者掌握相关技术并应用于实际项目中。数据分析、初盘数据、走地数据、分析管理系统、AI大模型预测系统、全自动化下单系统、智能娱乐竞猜系统-乐彩云......
  • Docker 实战:快速安装 Nginx、Redis、MySQL 等常用软件
    演示下如何使用Docker来完成Redis,Tomcat和MySQL等常用软件的安装。介绍了这几个常见的软件安装之后,以后想要安装其他软件,也是依样画葫芦即可。‍总体步骤一般来说,按照如下步骤来完成安装:搜索镜像拉取镜像查看镜像启动镜像(可能需要配置端口映射)容器的操作(例如启停)......