opencv将灰度图转为彩色图片

news2024/12/28 19:33:50

文章目录

  • 背景
    • 灰度图优势
    • opencv读取灰度图
    • 彩色转灰度算法
    • 需求
  • 方法
    • 测试代码

背景

在图像处理中通常需要将图片转为灰度图
灰度图,也称为灰度图像或黑白图像,是一种只包含亮度信息而不包含颜色信息的图像。在灰度图中,每个像素的亮度级别通常用0到255之间的整数表示,其中0表示黑色,255表示白色,中间的数值表示不同级别的灰色

灰度图优势

  • 简化计算:灰度图像是单通道图像,只有亮度信息,这大大减少了数据量,简化了计算过程。对于许多图像处理算法而言,处理单通道图像比处理多通道图像更快、更高效。
  • 减少噪声:彩色图像中的颜色信息会引入额外的噪声,尤其是在低光环境下拍摄的照片中。将图像转换为灰度图像可以帮助去除这种由颜色引起的噪声,从而更容易检测出重要的特征。
  • 便于分析:在很多计算机视觉任务中,如边缘检测、特征提取等,灰度图像可以更好地突出物体的轮廓和结构,有助于算法识别和理解图像中的关键元素。
  • 节省存储空间:由于灰度图像只有一个通道,因此存储灰度图像所需的存储空间比存储相同分辨率的彩色图像要少得多。
  • 提高算法鲁棒性:在某些应用场景下,如人脸识别、文字识别等,灰度图像可以提供足够的信息,同时减少由于光照条件变化导致的颜色变化对算法的影响,提高算法的鲁棒性。
  • 便于应用经典算法:许多经典的图像处理算法和理论都是基于灰度图像开发的,例如直方图均衡化、形态学操作、Sobel 边缘检测等。使用灰度图像可以让这些算法更易于实现和应用。
  • 降低带宽需求:在网络传输中,灰度图像的数据量较小,可以降低网络带宽的需求,这对于实时视频流等应用尤为重要。
  • 便于可视化:在某些情况下,灰度图像更容易观察和分析,特别是在医学影像领域,医生通常会查看灰度图像来进行诊断

opencv读取灰度图

img_gray = cv2.imread(“test,jpg”, cv2.IMREAD_GRAYSCALE) 

当使用 cv2.IMREAD_GRAYSCALE
选项读取图像时,读入的图像将自动转换为灰度图像,这意味着该图像只包含一个灰度通道而不是传统的 RGB 三通道。因此,img_gray只包含了亮度信息,而没有色彩信息

彩色转灰度算法

在OpenCV中,将彩色图像转换为灰度图像通常是通过计算彩色图像中每个像素的红、绿、蓝(RGB)三个颜色分量的加权平均值来实现的。最常用的加权方法是使用亮度(或灰度)感知的加权,因为人类对绿色的敏感度最高,对蓝色的敏感度最低

Gray=0.299×R+0.587×G+0.114×B

需求

在图像处理中,当我们将图片转换为灰度图并进行一系列处理后,得到的灰度图实际上已经丢失了原始的颜色信息。如何将灰度图直接“恢复”为彩色图

方法

  • 使用灰度图像作为单通道处理,然后复制该单通道图像三次,形成一个伪彩色图像。
  • 结合原始彩色图像和处理后的灰度图像,保留原始色彩信息的同时增强对比度

测试代码

import cv2
import numpy as np
import matplotlib.pyplot as plt


# 定义直方图均衡化函数
def histogram_equalization(image):
    # 应用直方图均衡化
    eq = cv2.equalizeHist(image)
    return eq

import numpy as np
from PIL import Image

def combine_enhanced_with_original_color2(enhanced_gray, original_color, output_path):
    # 加载增强对比度的灰度图像和原始的彩色图像
    #enhanced_gray = Image.open(enhanced_gray_image_path).convert('L')  # 转换为灰度模式
    #original_color = Image.open(original_color_image_path)
    print(enhanced_gray.size,original_color.size)
    # 检查两个图像尺寸是否一致,如果不一致则调整大小
    #if enhanced_gray.size != original_color.size:
    #    original_color = original_color.resize(enhanced_gray.size)

    # 将灰度图像转换为三通道图像
    enhanced_rgb = np.array(enhanced_gray).astype(np.float32)
    enhanced_rgb = np.stack((enhanced_rgb,) * 3, axis=-1)

    # 将原始彩色图像转换为numpy数组
    original_rgb = np.array(original_color).astype(np.float32)

    # 合并灰度图的对比度信息与彩色图的颜色信息
    # 这里简单地使用灰度图像作为亮度调整
    combined_image = np.clip(original_rgb * (enhanced_rgb / 255.), 0, 255).astype(np.uint8)

    # 创建一个新的PIL图像对象用于保存
    combined_image_pil = Image.fromarray(combined_image)
    return combined_image_pil
    # 保存结果图像
    #combined_image_pil.save(output_path)


# 定义结合增强后的灰度图像与原始彩色图像的函数
def combine_enhanced_with_original_color(original_color, enhanced_gray):
    # 将灰度图像转换为浮点型
    enhanced_gray_float = enhanced_gray.astype(np.float32)
    
    # 归一化灰度图像到 [0, 1] 区间
    enhanced_gray_normalized = cv2.normalize(enhanced_gray_float, None, 0, 10, cv2.NORM_MINMAX)
    
    # 将灰度图像作为亮度通道与原始彩色图像结合
    enhanced_color = np.zeros_like(original_color, dtype=np.float32)
    enhanced_color[:, :, 0] = original_color[:, :, 0] * enhanced_gray_normalized
    enhanced_color[:, :, 1] = original_color[:, :, 1] * enhanced_gray_normalized
    enhanced_color[:, :, 2] = original_color[:, :, 2] * enhanced_gray_normalized
    
    # 将结果转换回 uint8 类型
    enhanced_color = np.clip(enhanced_color * 255, 0, 255).astype(np.uint8)
    
    return enhanced_color
	
# 读取原始彩色图像
image_path = 'js-test01.jpg'
img_color = cv2.imread(image_path)
img_color = cv2.cvtColor(img_color, cv2.COLOR_BGR2RGB)  # 转换为 RGB 格式以正确显示颜色

# 将彩色图像转换为灰度图像
img_gray = cv2.cvtColor(img_color, cv2.COLOR_RGB2GRAY)

# 对灰度图像进行对比度增强
enhanced_img = histogram_equalization(img_gray)

# 将增强后的灰度图像作为亮度通道与原始彩色图像结合
#enhanced_color = combine_enhanced_with_original_color(img_color, img_gray)
enhanced_color = combine_enhanced_with_original_color2(img_gray,img_color,"")


# 展示图像
plt.figure(figsize=(12, 6))

plt.subplot(1, 3, 1) 
plt.imshow(img_color)
plt.title('original')
plt.axis('off')

plt.subplot(1, 3, 2)
plt.imshow(img_gray)
plt.title('img_gray')
plt.axis('off')

plt.subplot(1, 3, 3)
plt.imshow(enhanced_color)
plt.title('enhanced_color')
plt.axis('off')


plt.tight_layout()
plt.show()

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【STL中容器汇总】map、list、vector等详解

容器学习分享 1、STL简介1.1、STL六大组件 2、vector容器2.1、vector 基本操作2.2、vector容器示例2.3、vector容器存放自定义数据类型示例2.3、vector嵌套vector示例 3、list 容器3.1使用示例3.2、list容器基本函数 4、map容器4.1、map函数原型4.2、map函数示例 1、STL简介 ST…

pdf文件怎么编辑?7大常用的pdf在线编辑技巧,免费好用!

编辑pdf文件通常涉及对文本、图片及其他内容的添加、删除或修改。无论您希望清除过时的信息,还是想为pdf文件增添一些补充材料,掌握几种简单有效的编辑方法都是非常重要的。因此,本文将为大家介绍7大常用的pdf在线编辑技巧,详细解…

Java学习Day40:大战亢金龙!(spring框架之AOP)

AOP(面向切面变成):不改变原有代码的情况下,对代码进行功能添加 1.一些概念 抽取出的方法:通知 原始方法:成为连接点(可以是程序执行中的任意位置),对应原始的一个个方…

Qt篇——Qt在msvc编译下提示“C2001:常量中有换行符“的错误

在pro文件中添加以下配置即可: msvc{QMAKE_CFLAGS /utf-8QMAKE_CXXFLAGS /utf-8 }

哈希表、算法

哈希表 hash: 在编程和数据结构中,"hash" 通常指的是哈希函数,它是一种算法,用于将数据(通常是字符 串)映射到一个固定大小的数字(哈希值)。哈希函数在哈希表中尤为重要…

什么是浏览器指纹及其在线跟踪的用途?

互联网常常给人一种广阔的蓝色天空的感觉,在那里你可以自由航行,只有匿名才能提供这种自由。然而,事实并非如此。有一套工具被希望识别谁在访问其网站的企业广泛使用。这套工具被称为浏览器指纹识别,了解它的使用方式很重要。 一…

剑指offer JZ23 链表中环的入口结点

问题描述: 给定一个长度为n的链表,首先判断其是否有环,然后找到环的入口。 要求:空间复杂度 O(1),时间复杂度 O(n)。 思路: 1. 投机一点的做法 从头遍历链表,如果有环,那么有些节…

Docker初识(Docker技术集群与应用)

一、基础设施即服务 IaaS(Infrastructure as a Service) eg:购买的云服务器,就是IaaS 提供给客户的服务是对所有设施的利用,包括处理、存储、网络和其他基本的计算资源。客户能够部署和运行任意软件,包括…

LLM大模型学习:探索LLM的精髓-理解Prompts概念与LangChain快速应用技巧”

LLM 中什么是Prompts?如何使用LangChain 快速实现Prompts 一 Prompt是一种基于自然语言处理的交互方式,它通过机器对自然语言的解析,实现用户与机器之间的沟通。 Prompt主要实现方式是通过建立相应的语料库和语义解析模型,来将自…

《A Few Useful Things to Know about Machine Learning》论文导读

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl机器学习作为人工智能领域的重要分支,近年来得到了广泛的关注和应用。Pedro Domingos的经典论文《A Few Useful Things to Know about Machine Learning》为我们提供了对机器学习深入且全面的理解…

Java方法的定义,即“函数“的定义!

方法的作用 提高代码的复用性,写一次,你需要的时候直接去调用即可。 定义一个函数方法 [修饰符1 修饰符2 ...] 返回值类型 方法名(形参){Java语句;... ... ... }初次接触方法的举例:两个整数的求和方法 根据上面的例子我们来分…

虚拟机扩充磁盘空间

本人使用的VMware首先关闭虚拟机在设置中进行磁盘扩展,输入扩展的空间 具体扩展步骤 fdisk /dev/sda输入p,查看分区情况输入n新建一个分区,还有之后两步,全部默认输入w保存分区fdisk -l使用vgdisplay查看卷组信息:vgdi…

动手学深度学习(pytorch)学习记录26-卷积神经网路(LeNet)[学习记录]

目录 LeNet模型训练 LeNet 总体来看,LeNet(LeNet-5)由两个部分组成: 卷积编码器:由两个卷积层组成; 全连接层密集块:由三个全连接层组成。 每个卷积块中的基本单元是一个卷积层、一个sigmoid激活函数和平均…

Docker 清理和查看镜像与容器占用情况

查看容器占用磁盘大小 docker system df 查看单个image、container大小: docker system df -v 清理所有废弃镜像与Build Cache docker system prune -a

【解决内存泄漏的问题】 Qt 框架中的父子对象关系会自动管理内存,父对象会在其销毁时自动销毁所有子对象。

修改前的代码 这段代码可能会出现内存泄漏问题,主要原因是构造函数中创建的 LoginDialog 和 RegisterDialog 对象未在合适的地方被正确释放。具体分析如下: 1. 构造函数中的问题 _login_dlg new LoginDialog(); setCentralWidget(_login_dlg); _login…

【北京迅为】《STM32MP157开发板使用手册》- 第十二章 编译Linux内核

iTOP-STM32MP157开发板采用ST推出的双核cortex-A7单核cortex-M4异构处理器,既可用Linux、又可以用于STM32单片机开发。开发板采用核心板底板结构,主频650M、1G内存、8G存储,核心板采用工业级板对板连接器,高可靠,牢固耐…

运算放大器中的反馈

运算放大器中的反馈:原理、类型与应用 运算放大器(Operational Amplifier, 简称Op-Amp)是现代电子电路中的重要组成部分,被广泛应用于信号处理、放大、滤波等场合。而反馈技术则是运算放大器电路的核心之一,直接影响其…

代码随想录算法训练营第二十二天| 491. 递增子序列、46. 全排列、47. 全排列Ⅱ

今日内容 Leetcode. 491 递增子序列Leetcode. 46 全排列Leetcode. 47 全排列Ⅱ Leetcode. 491 递增子序列 文章链接:代码随想录 (programmercarl.com) 题目链接:491. 非递减子序列 - 力扣(LeetCode) 本题也是一个子集问题&#…

【AI绘画】Midjourney后置指令--seed、--tile、--q、--chaos、--w、--no详解

博客主页: [小ᶻZ࿆] 本文专栏: AI绘画 | Midjourney 文章目录 💯前言💯Midjourney后置指令--seed测试1测试2如何获取未指定种子图片的随机种子注意点 💯Midjourney后置指令--tile测试 💯Midjourney后置指令--q(or-…

Retrieval-based-Voice-Conversion-WebUI模型构建指南

一、模型介绍 Retrieval-based-Voice-Conversion-WebUI(简称 RVC)模型是一个基于 VITS(Variational Inference with adversarial learning for end-to-end Text-to-Speech)的简单易用的语音转换框架。 具有以下特点 简单易用&a…