opencv判断灰化情况

目的

先说说理论:
在图像处理中,用RGB三个分量(R:Red,G:Green,B:Blue),即红、绿、蓝三原色来表示真彩色,R分量,G分量,B分量的取值范围均为0~255,比如电脑屏幕上的一个红色的像素点的三个分量的值分别为:255,0,0。
那么什么叫图片的灰度化呢?其实很简单,就是让像素点矩阵中的每一个像素点都满足下面的关系:R=G=B(就是红色变量的值,绿色变量的值,和蓝色变量的值,这三个值相等,“=”的意思不是程序语言中的赋值,是数学中的相等),此时的这个值叫做灰度值。
这是理论,实际在Opencv中,灰度化就是单通道图了,因为RGB都一样了,没必要都存储了。
再说说具体目的:
目的就是判断一个图片是否灰化了。
网上,包括,AI上很多方法都不行。

分析

先把一张简单的图片进行灰化操作:

void productGrayImage()
{
    cv::Mat image(10, 10, CV_8UC3);
    // 遍历图像的每个像素
    for (int x = 0; x < image.rows; ++x) {
        for (int y = 0; y < image.cols; ++y) {
            // 获取像素的指针
            cv::Vec3b& pixel = image.at<cv::Vec3b>(x, y);
            // 为BGR通道分别赋值
            pixel[0] = 255; // 蓝色通道 (B)
            pixel[1] = 9; // 绿色通道 (G)
            pixel[2] = 10;   // 红色通道 (R)
        }
    }
    image.at<cv::Vec3b>(0, 0)[0] = 255;
    image.at<cv::Vec3b>(0, 0)[1] = 255;
    image.at<cv::Vec3b>(0, 0)[2] = 255;
    printf("image.type=%d\n", image.type());
    // 显示图像
    cv::imshow("Colored Image", image);
    cv::cvtColor(image, image, cv::COLOR_BGR2GRAY);
    printf("image.type=%d\n", image.type());
    for (int x = 0; x < image.rows; ++x)
    {
        for (int y = 0; y < image.cols; ++y)
        {
            // 获取像素的指针
           int pixel = image.at<uchar>(x, y);
           printf("%d ",pixel);
        }
        printf("\n");
    }
//    cv::imwrite("gray.jpg", image);
    cv::imshow("gray Image", image);
    cv::imwrite("gray.bmp", image);
}

运行情况:
在这里插入图片描述

生成gray.bmp的情况:
在这里插入图片描述

下面判断是否灰化:

void judgeGrayImageInfo(QString imagePath)
{
    //cv::Mat image = cv::imread(imagePath.toStdString(), cv::IMREAD_GRAYSCALE); // 加载图像
    QImage image = QImage(imagePath);
    qDebug()<<"image.colorCount="<<image.colorCount();
    qDebug()<<"image.format="<<image.format();
    cv::Mat mat = cv::imread(imagePath.toStdString()); // 加载图像
    qDebug()<<"mat.type="<<mat.type();
    for (int i = 0; i < mat.rows; i++)
    {
        for (int j = 0; j < mat.cols; j++)
        {
            if(mat.type() == 16)
            {
                cv::Vec3b pixel = mat.at<cv::Vec3b>(i, j);
                printf("%d,%d,%d ", pixel[0], pixel[1], pixel[2]);
            }
            else
            {
                int pixel = mat.at<uchar>(i, j);
                printf("%d ", pixel);
            }
        }
        printf("\n");
    }
    if (isGrayImage(mat)) {
        std::cout << "The image is grayscale." << std::endl;
    } else {
        std::cout << "The image is not grayscale." << std::endl;
    }
    cv::imshow("gray Image", mat);
    cv::Mat mats[3];
    split(mat,mats);
    cv::imshow("gray gray Image", mat);
    mat = mats[0];
    int uniqueColors = cv::countNonZero(mat);
     qDebug()<<"uniqueColors="<<uniqueColors;
     qDebug()<<"mat.type="<<mat.type();
     if(mat.type() == 0)
     {
         mat.at<uchar>(0, 1) = 255;
         mat.at<uchar>(0, 2) = 255;
     }
     for (int i = 0; i < mat.rows; i++)
     {
         for (int j = 0; j < mat.cols; j++)
         {
             if(mat.type() == 16)
             {
                 cv::Vec3b pixel = mat.at<cv::Vec3b>(i, j);
                 printf("%d,%d,%d ", pixel[0], pixel[1], pixel[2]);
             }
             else
             {
                 int pixel = mat.at<uchar>(i, j);
                 printf("%d ", pixel);
             }
         }
         printf("\n");
     }
}

运行情况:

在这里插入图片描述
在这里插入图片描述

可以见得,能正确判断是否灰化

总结

灰化是怎么判断的呢?
灰化图在opencv中是单通道图,但保存时,会转化成RGB模式的图。
所以,再加载,通过通道数,判断是否是灰度图,这样是不对的。
解决方法:
首先,一个图片在保存时,其实是以RGB模式保存的,这也是操作系统默认的保存方式。
那一个灰化图在保存时,会默认转化为RGB模式,怎么转化,其就是把一个灰化值重复为三份,分别对应RGB,这样就可以了。
如图所示:
在这里插入图片描述

知道这个情况了:
就知道如何判断一个图是否灰化了:
那就是:R=G=B就可以了。
具体代码见:
https://download.csdn.net/download/maokexu123/88862864

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/403318.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用单一ASM-HEMT模型实现从X波段到Ka波段精确的GaN HEMT非线性仿真

来源&#xff1a;Accurate Nonlinear GaN HEMT Simulations from X- to Ka-Band using a Single ASM-HEMT Model 摘要&#xff1a;本文首次研究了ASM-HEMT模型在宽频带范围内的大信号准确性。在10、20和30 GHz的频率下&#xff0c;通过测量和模拟功率扫描进行了比较。在相同的频…

树-王道-复试

树 1.度&#xff1a; 树中孩子节点个数&#xff0c;所有结点的度最大值为 树的度 2.有序树&#xff1a; 逻辑上看&#xff0c;树中结点的各子树从左至右是有次序的&#xff0c;不能互换。 **3.**树的根节点没有前驱&#xff0c;其他节点只有一个前驱 **4.**所有节点可有零个或…

备战蓝桥杯—— 双指针技巧巧答链表4

对于单链表相关的问题&#xff0c;双指针技巧是一种非常广泛且有效的解决方法。以下是一些常见问题以及使用双指针技巧解决&#x1f680;&#x1f680;&#xff1a; 合并两个有序链表&#xff1a; 使用两个指针分别指向两个链表的头部&#xff0c;逐一比较节点的值&#xff0c;…

CI/CD 之 gitlab-runner 注册执行器与踩坑

前言 上一篇已经讲了 gitlab-runner 的部署方法&#xff0c;这一篇我们来讲一下如何注册 gitlab-runner 执行器并创建作业 一、添加 .gitlab-ci.yml 配置文件 在需要注册 CI/CD 的项目中&#xff0c;增加一个 .gitlab-ci.yml 的配置文件 基本模板配置如下&#xff1a; sta…

【Python笔记-设计模式】桥接模式

一、说明 桥接模式是一种结构型设计模式&#xff0c; 主要用于将抽象部分与它的实现部分分离&#xff0c; 从而能在开发时分别使用&#xff0c;使系统更加灵活&#xff0c;易于扩展。 (一) 解决问题 所有 组合类的数量将以几何级数增长 抽象和实现分离&#xff1a;桥接模式可…

音视频技术-声反馈啸叫的产生与消除

目录 1.均衡调节: 2.移频法: 3.移相法: 4.比较法: 在扩音系统中,产生啸叫危害很大,一方面影响会议、演出等活动的正常进行,另一方面严重的啸叫会导致音响设备的损坏。 “啸叫”是“声反馈”的俗称,形成的机制复杂,消除的手段多样,专业调音师也对

Spring Boot中实现列表数据导出为Excel文件

点击下载《Spring Boot中实现列表数据导出为Excel文件》 1. 前言 本文将详细介绍在Spring Boot框架中如何将列表数据导出为Excel文件。我们将通过Apache POI库来实现这一功能&#xff0c;并解释其背后的原理、提供完整的流程和步骤&#xff0c;以及带有详细注释的代码示例。最…

【笔记】深度学习入门:基于Python的理论与实现(二)

神经网络的学习&#xff08;神经网络的学习阶段&#xff0c;不是我们学习神经网络&#xff09; 从数据中学习 训练数据和测试数据 机器学习中&#xff0c;一般将数据分为训练数据和测试数据两部分来进行学习和 实验等。首先&#xff0c;使用训练数据进行学习&#xff0c;寻找最…

wondows10用Electron打包threejs的项目记录

背景 电脑是用的mac&#xff0c;安装了parallels desktop ,想用electron 想同时打包出 苹果版本和windows版本。因为是在虚拟机里安装&#xff0c;它常被我重装&#xff0c;所以记录一下打包的整个过程。另外就是node生态太活跃&#xff0c;几个依赖没记录具体版本&#xff0…

软考29-上午题-【数据结构】-排序

一、排序的基本概念 1-1、稳定性 稳定性指的是相同的数据所在的位置经过排序后是否发生变化。若是排序后&#xff0c;次序不变&#xff0c;则是稳定的。 1-2、归位 每一趟排序能确定一个元素的最终位置。 1-3、内部排序 排序记录全部存放在内存中进行排序的过程。 1-4、外部…

六.生成makefile文件 并基于makefile文件编译opencv

1.点击【Generate】 生成makefile文件 2.进入目录下编译opencv源码&#xff0c;mingw32-make -j 8 3..编译出现报错 4.取消[WITH_OPENCL_D3D11_NV]选项&#xff0c;再次【configure】【generate】 然后再次编译&#xff1a;mingw32-make -j 8

缓存篇—缓存雪崩

什么是缓存雪崩 通常我们为了保证缓存中的数据与数据库中的数据一致性&#xff0c;会给 Redis 里的数据设置过期时间&#xff0c;当缓存数据过期后&#xff0c;用户访问的数据如果不在缓存里&#xff0c;业务系统需要重新生成缓存&#xff0c;因此就会访问数据库&#xff0c;并…

【结合OpenAI官方文档】解决Chatgpt的API接口请求速率限制

OpenAI API接口请求速率限制 速率限制以五种方式衡量&#xff1a;RPM&#xff08;每分钟请求数&#xff09;、RPD&#xff08;每天请求数&#xff09;、TPM&#xff08;每分钟令牌数&#xff09;、TPD&#xff08;每天令牌数&#xff09;和IPM&#xff08;每分钟图像数&#x…

1.CSS单位总结

CSS 单位总结 经典真题 px 和 em 的区别 CSS 中的哪些单位 首先&#xff0c;在 CSS 中&#xff0c;单位分为两大类&#xff0c;绝对长度单位和相对长度单位。 绝对长度单位 我们先来说这个&#xff0c;绝对长度单位最好理解&#xff0c;和我们现实生活中是一样的。在我们…

基于SSH打通隧道实现异地组网

前言 最近有异地组网的需求&#xff0c;我目前的是用蒲公英X1盒子来进行组网&#xff0c;但是蒲公英X1非会员账号有设备限制3个&#xff08;这个是硬伤&#xff09;&#xff0c;虽然说可以打通P2P但是在复杂的网络环境下概率不是特别高 所以研究下SSH异地组网的方式&#xff…

《图解HTTP》笔记2:http的构成

1&#xff0c;查看浏览器上面一个具体的http请求 浏览器地址栏输入网址&#xff1a;https://news.baidu.com/ 使用浏览器的开发者工具&#xff0c;查看网络中发送和接受的数据。 可以看到输入一个网址&#xff0c;浏览器和服务器进行了很多的交互。&#xff08;绿色部分&#…

Docker容器故障排查与解决方案

Docker是一种相对使用较简单的容器&#xff0c;我们可以通过以下几种方式获取信息&#xff1a; 1、通过docker run执行命令&#xff0c;或许返回信息 2、通过docker logs 去获取日志&#xff0c;做有针对性的筛选 3、通过systemctl status docker查看docker服务状态 4、通过…

详细分析Python中的unittest测试框架

目录 1. 基本知识2. API2.1 断言2.2 setUp() 和 tearDown() 3. Demo 1. 基本知识 unittest 是 Python 标准库中的一个单元测试框架&#xff0c;用于编写和执行测试用例以验证代码的正确性 提供了一种结构化的方法来编写测试&#xff0c;使得测试代码更加模块化和易于维护 以…

【kubernetes】二进制部署k8s集群之cni网络插件flannel和calico工作原理(中)

↑↑↑↑接上一篇继续部署↑↑↑↑ 目录 一、k8s集群的三种接口 二、k8s的三种网络模式 1、pod内容器之间的通信 2、同一个node节点中pod之间通信 3、不同的node节点的pod之间通信 Overlay Network VXLAN 三、flannel网络插件 1、flannel插件模式之UDP模式&#xff0…

在 Windows 上使用 VC++ 编译 OpenSSL 源码的步骤

在 Windows 上使用 VC 编译 OpenSSL 源码的步骤如下&#xff1a; 准备工作 安装 Visual Studio 2017 或更高版本。安装 Perl 脚本解释器。安装 NASM 汇编器。 编译步骤 下载 OpenSSL 源码。解压 OpenSSL 源码。打开命令行工具&#xff0c;并进入 OpenSSL 源码目录。运行以下…