图像基础,C++,python灰度图转换_c++改灰度图并储存-程序员宅基地

技术标签: 算法  卷积  python  计算机视觉  # 机器学习  opencv  

一丶图像存储格式分类

在这里插入图片描述

分类 特点 举例
黑白图像 二值图像只有黑白两种颜色,一个像素仅占1,0表示黑,1表示白,或相反 在这里插入图片描述
8位索引图像 8位灰度索引图像中map也就是颜色表红、绿、蓝分量值相等 8位伪彩色索引图像,颜色表红、绿、蓝分量值不全相等 在这里插入图片描述
24位真彩图 .RGB图像也就是每个像素点3个8位的分量 在这里插入图片描述

二丶图像存储格式转换

  1. 伪彩色彩 → 灰度 :直接改该索引表,将三个分量改成与索引号一致的
  2. 灰度 → 伪彩色彩:不好变,每个分量可能需要人为指定
  3. 灰度图与RGB图像转换:任何颜色都有红、绿、蓝三原色组成,假如原来某点的颜色为RGB(R,G,B),那么,我们可以通过下面几种方法,将其转换为灰度:

1.浮点算法:Gray = R * 0.3+G * 0.59+B * 0.11
2.整数方法:Gray = (R * 30+G * 59+B * 11) / 100
3.移位方法:Gray = (R * 76+G * 151+B * 28) >> 8;
4.平均值法:Gray = (R+G+B) / 3;
5.仅取绿色:Gray=G;
通过上述任一种方法求得Gray后,将原来的RGB(R,G,B)中的R,G,B统一用Gray替换,形成新的颜RGB(Gray,Gray,Gray),用它替换原来的RGB(R,G,B)就是灰度图了。

所以RGB可以转化为灰度图,RGB的红色、绿色、蓝色三个通道的缩览图都是以灰度显示的

三丶C++ bmp 转灰度实例

1. bmp文件组成

在这里插入图片描述

在这里插入图片描述
重要的有(上面的名字都是标准的)

  1. bfType:可以用来判断当前图片是否为bmp图像,若读出来是“BM”那就是
  2. biBitCount 每个像素所需要的位数,比如单色位图需要1位,8位索引图像需要8位,真彩色就是24位
  3. 调色板 就是红绿蓝和保留字

2. bmp读取与灰度转换(C++)

重要函数:

  1. int fread(void *ptr, int size, int nitems, FILE *stream);
    从一个流中读数据,从所给的输入流stream中读取的nitems项数据,每一项数据长度为size字节,到由ptr所指的块中,读出的数据在流中会消失
  2. int fwrite(void *ptr, int size, int nitems, FILE *stream);

从ptr所指的块中读数据读取的nitems项数据,每一项数据长度为size字节,输入到由流stream
3. FILE *fopen(const char *filename, const char *mode)
使用给定的模式 mode 打开 filename 所指向的文件
w:以“写入”方式打开文件。如果文件不存在,那么创建一个新文件;如果文件存在,那么清空文件内容(相当于删除原文件,再创建一个新文件)。
r:只读方式打开,将文件指针指向文件头。
b :字符用来告诉函数库以二进制模式打开文件

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include <iostream>
using namespace std;

/*
位图头结构
*/
#pragma pack(1)
typedef struct tagBITMAPFILEHEADER
{
    
    unsigned char bfType[2];//文件格式
    unsigned long bfSize;//文件大小
    unsigned short bfReserved1;//保留
    unsigned short bfReserved2;
    unsigned long bfOffBits; //DIB数据在文件中的偏移量
}fileHeader;
#pragma pack()
/*
位图数据信息结构
*/
#pragma pack(1)
typedef struct tagBITMAPINFOHEADER
{
    
    unsigned long biSize;//该结构的大小
    long biWidth;//文件宽度
    long biHeight;//文件高度
    unsigned short biPlanes;//平面数
    unsigned short biBitCount;//颜色位数
    unsigned long biCompression;//压缩类型
    unsigned long biSizeImage;//DIB数据区大小
    long biXPixPerMeter;
    long biYPixPerMeter;
    unsigned long biClrUsed;//多少颜色索引表
    unsigned long biClrImporant;//多少重要颜色
}fileInfo;
#pragma pack()
/*
调色板结构
*/
#pragma pack(1)
typedef struct tagRGBQUAD
{
    
    unsigned char rgbBlue; //蓝色分量亮度
    unsigned char rgbGreen;//绿色分量亮度
    unsigned char rgbRed;//红色分量亮度
    unsigned char rgbReserved;
}rgbq;
#pragma pack()

//显示位图文件头信息
void showBmpHead(fileHeader pBmpHead) {
    
    cout << "位图文件头:" << endl;
    cout << "文件大小:" << pBmpHead.bfSize << endl;
    cout << "保留字_1:" << pBmpHead.bfReserved1 << endl;
    cout << "保留字_2:" << pBmpHead.bfReserved2 << endl;
    cout << "实际位图数据的偏移字节数:" << pBmpHead.bfOffBits << endl << endl;
}

void showBmpInfoHead(fileInfo pBmpInforHead) {
    
    cout << "位图信息头---------" << endl;
    cout << "结构体的长度:" << pBmpInforHead.biSize << endl;
    cout << "位图宽:" << pBmpInforHead.biWidth << endl;
    cout << "位图高:" << pBmpInforHead.biHeight << endl;
    cout << "biPlanes平面数:" << pBmpInforHead.biPlanes << endl;
    cout << "biBitCount采用颜色位数:" << pBmpInforHead.biBitCount << endl;
    cout << "压缩方式:" << pBmpInforHead.biCompression << endl;
    cout << "biSizeImage实际位图数据占用的字节数:" << pBmpInforHead.biSizeImage << endl;
    cout << "X方向分辨率:" << pBmpInforHead.biXPixPerMeter << endl;
    cout << "Y方向分辨率:" << pBmpInforHead.biYPixPerMeter << endl;
    cout << "使用的颜色数:" << pBmpInforHead.biClrUsed << endl;
    cout << "重要颜色数:" << pBmpInforHead.biClrImporant << endl;
}

#define      PI    3.141592653
#pragma once
 

int main()
{
    
   
    int i, j, k;
    FILE* fpBMP, * fpGray;
    fileHeader* fh;
    fileInfo* fi;
    rgbq* fq;

    if ((fpBMP = fopen("C:\\Users\\Administrator\\Desktop\\real.bmp", "rb")) == NULL)
    {
    
        printf("打开文件失败");
        exit(0);
    }

    if ((fpGray = fopen("C:\\Users\\Administrator\\Desktop\\22.bmp", "wb")) == NULL)
    {
    
        printf("创建文件失败");
        exit(0);
    }

   
    fh = (fileHeader*)malloc(sizeof(fileHeader));
    fi = (fileInfo*)malloc(sizeof(fileInfo));
    //读取位图头结构和信息头
    fread(fh, sizeof(fileHeader), 1, fpBMP);
    showBmpHead(*fh);

    cout << fh->bfType[0] << fh->bfType[1] << endl;
    fread(fi, sizeof(fileInfo), 1, fpBMP);
    showBmpInfoHead(*fi);
    //修改头信息
    fi->biBitCount = 8;
    fi->biSizeImage = ((fi->biWidth * 3 + 3) / 4) * 4 * fi->biHeight;
    //fi->biClrUsed=256;

    fh->bfOffBits = sizeof(fileHeader) + sizeof(fileInfo) + 256 * sizeof(rgbq);
    fh->bfSize = fh->bfOffBits + fi->biSizeImage;

    //创建调色版
    fq = (rgbq*)malloc(256 * sizeof(rgbq));
    for (i = 0; i < 256; i++)
    {
    
        fq[i].rgbBlue = fq[i].rgbGreen = fq[i].rgbRed = i;
        //fq[i].rgbReserved=0;
    }
    //将头信息写入
    fwrite(fh, sizeof(fileHeader), 1, fpGray);
    fwrite(fi, sizeof(fileInfo), 1, fpGray);
    fwrite(fq, sizeof(rgbq), 256, fpGray);


    /*存储RGB图像的一行像素点*/
    unsigned char ImgData[3000][3];
    /*将灰度图的像素存到一个一维数组中*/

    unsigned char* data;
    int h = fi->biHeight;
    int w = (fi->biWidth + 3) / 4 * 4;
    data = (unsigned char*)malloc(h*w);



    //读取RGB图像素并转换为灰度值
    
    for (i = 0; i <h; i++)
    {
    
        for (j = 0; j < w; j++)
        {
    
            for (k = 0; k < 3; k++) {
    
                fread(&ImgData[j][k], 1, 1, fpBMP);
            *(data + i *w + j) = int((float)ImgData[j][0] * 0.114 +
                (float)ImgData[j][1] * 0.587 +
                (float)ImgData[j][2] * 0.299);
                
        }
        
   
    }
    
    fwrite(data, sizeof(unsigned char), h*w, fpGray);
   

    free(fh);
    free(fi);
    free(fq);
    fclose(fpBMP);
    fclose(fpGray);
    printf("success\n");
    return 0;
}

四丶Python 灰度图转

python代码

程序的实现

from PIL import Image
img = Image.open('lena.png')
gray_img = img.convert('L')

模式“L”为灰色图像公式:L = R * 299/1000 + G * 587/1000+ B * 114/1000

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_42146775/article/details/104757348

智能推荐

视频教程-跟一夫学UI设计 APPUI综合设计与图标实战案例视频教程 photoshop绘制icon案例-UI-程序员宅基地

文章浏览阅读104次。跟一夫学UI设计 APPUI综合设计与图标实战案例视频教程 photoshop绘制icon案例 ..._app风格案例视频

vue 海康视频播放_vue-hkvideo-程序员宅基地

文章浏览阅读4k次,点赞4次,收藏22次。1. 下载并安装海康 web 插件https://open.hikvision.com/download/5c67f1e2f05948198c909700?type=102. 把上一步解压的三个 js, 复制到你的项目中, 根据路径, 自己引入到 index.html 中3. 建议运行它的 demo, 大概看看代码, 了解一下它的大致结构, 它的注解很详细, 3 分钟就能看完4. 贴上我的代码(我的是每次只显示一个画面, 点击摄像头切换画面)<temp.._vue-hkvideo

html li 鼠标经过变色,CSS实现li标签鼠标经过时改变背景颜色-程序员宅基地

文章浏览阅读5.3k次,点赞3次,收藏4次。很多时候需要用到这个css效果,实际上就用了一个li标签的热点样式,不仅是li标签,div等也可以的完整代码如下,div/css鼠标热点改变li标签背景颜色body{ background-color:#CCCC99; margin:0; padding:0; color:#fff;}ul{ margin:0; padding:50px;}li{ list-style:none; height:2..._ul li 样式 鼠标移入颜色

数据恢复:在 Linux 上恢复删除了的文件_linux系统,删了某一个文件夹的数据还清空了回收站,还能不能找回来我的数据-程序员宅基地

文章浏览阅读238次,点赞4次,收藏8次。把删除创建为rm -i 的别名当 -i 选项配合 rm 命令(也包括其他文件处理命令比如 cp 或者 mv)使用时,在删除文件前会出现一个提示。其中,/home/gacanepa/rescued 是另外一个磁盘中的目录 - 请记住,把文件恢复到被删除文件所在的磁盘中不是一个明智的做法。安装完成后,我们做一个简单的测试吧。如果在恢复过程中,占用了被删除文件之前所在的磁盘分区,就可能无法恢复文件。但愿你对于你的文件足够小心,当你要从外部磁盘或 USB 设备中恢复丢失的文件时,你只需使用这个工具即可。

2021-09-15 WPF上位机 15-属性绑定(数据格式化)_wpf 自定义属性绑定 格式化 实现-程序员宅基地

文章浏览阅读3.2w次。<Window x:Class="Zhaoxi.BindingStudy.DataFormatStudy.DataFormatStudyWin" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.._wpf 自定义属性绑定 格式化 实现

[常用办公软件] wps怎么自动生成目录?wps自动生成目录的设置教程_wps目录自动生成-程序员宅基地

文章浏览阅读1.1w次,点赞3次,收藏5次。转载请说明来源于"厦门SEO"本文地址:http://www.96096.cc/Article/160880.html常用办公软件  WPS Office是由金山软件股份有限公司开发的一款针对个人永久免费的办公软件,在我们的日常生活和工作中,WPS Office比起微软Microsoft Office来说在文字上的处理会更深入国人用户的人心,熟悉操作WPS的办公小技巧,能够更高效的提高我们的工作效率,今天小编要为大家分享的是WPS怎么自动生成目录?快来一起看看WPS自动生成目录的设置教程吧。_wps目录自动生成

随便推点

go http框架下的静态资源代理实现(压缩,缓存验证自定义)

之前在说了我的第一版静态资源代理,后面我又完善了一下:照着以上思路,可以在其他语言其他框架中实现,因为对框架没有依赖,都是使用的一些基本功能。

RecyclerView实现吸顶效果项目实战(三):布局管理器LayoutManager-程序员宅基地

文章浏览阅读338次,点赞4次,收藏6次。架构师不是天生的,是在项目中磨练起来的,所以,我们学了技术就需要结合项目进行实战训练,那么在Android里面最常用的架构无外乎 MVC,MVP,MVVM,但是这些思想如果和模块化,层次化,组件化混和在一起,那就不是一件那么简单的事了,我们需要一个真正身经百战的架构师才能讲解透彻其中蕴含的深理。此时,RecyclerView第一个item是添加进Adapter中的最后一个,最后一个item是第一个加进Adapter的数据,RecyclerView会自动滑到末尾,另外item整体是依靠下方的。

【智能排班系统】基于AOP和自定义注解实现接口幂等性-程序员宅基地

文章浏览阅读884次。使用多种方式实现接口幂等性,通过定义注解方便对方法进行幂等性控制

SpringBoot整合Swagger2 详解_springboot swagger2 开关-程序员宅基地

文章浏览阅读324次。SpringBoot、Swagger2 整合详解_springboot swagger2 开关

spring boot 项目报错 java.sql.SQLException: The server time zone value '�й���׼ʱ��' is unrecognized_springboot项目里面报错 the server time zone value ' й-程序员宅基地

文章浏览阅读2.8w次,点赞96次,收藏115次。报错说是时区不对因为mysql-connection-java版本导致时区的问题。pom.xml:控制台报错信息:java.sql.SQLException: The server time zone value ‘�й���׼ʱ��’ is unrecognized or represents more than one time zone. You must configure ei..._springboot项目里面报错 the server time zone value ' й

最全Android Kotlin 学习路线(Kotlin 从入门、进阶到实战)_kotlin学习-程序员宅基地

文章浏览阅读4.2k次。Kotlin 是由 jetBrains 开发的一门现代多平台应用的静态编程语言,Kotlin 代码即可以编译成 Java 字节码,又可以编译成 JavaScript,Kotlin 是开源的,源码在这。Kotlin 包含了大量的语法糖,在编码的时候,会大大的简化我们的代码量及工作效率。且相比传统的 Java 语言,Kotlin 种大量的简写,可以减少很多用Java 必须要写的样板代码,减少大量的 if…else 等嵌套,减少大量接口的实现,代码结构也会更加清晰。_kotlin学习