C++-灰度图上色GrayToColor

article/2025/8/29 22:23:21

作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

场景需求

       最近有客户提出,想要将解包裹图像转化为有颜色的图像,具备更佳的视觉效果。解包裹图是一个float类型的灰度图像,里面的数值范围类似于从-10.25到20.56这种,客户想要最低的数值为蓝色,最高的数值为红色,中间的数值为绿色。

       针对该需求,我们首先需要将灰度值图转化为0-255的8通道(uchar)灰度图,运用归一化函数可以实现,之后考虑到颜色和灰度的关系,比如最低的颜色为蓝色(0,0,255)对应灰度值0,最高的颜色为红色(255,0,0)对应灰度值255,只需要找出其变化的规律即可。

       下方为具体实现函数和测试代码。

功能函数代码

/*** @brief GrayToColor                      灰度图上色* @param phase                            输入的灰色图像,通道为1* @return                                 上色后的图像*/
static cv::Mat GrayToColor(cv::Mat &phase)
{CV_Assert(phase.channels() == 1);cv::Mat temp, result, mask;// 将灰度图重新归一化至0-255cv::normalize(phase, temp, 255, 0, cv::NORM_MINMAX);temp.convertTo(temp, CV_8UC1);// 创建掩膜,目的是为了隔离nan值的干扰mask = cv::Mat::zeros(phase.size(), CV_8UC1);mask.setTo(255, phase == phase);// 初始化三通道颜色图cv::Mat color1, color2, color3;color1 = cv::Mat::zeros(temp.size(), temp.type());color2 = cv::Mat::zeros(temp.size(), temp.type());color3 = cv::Mat::zeros(temp.size(), temp.type());int row = phase.rows;int col = phase.cols;// 基于灰度图的灰度层级,给其上色,最底的灰度值0为蓝色(255,0,0),最高的灰度值255为红色(0,0,255),中间的灰度值127为绿色(0,255,0)// 不要惊讶蓝色为什么是(255,0,0),因为OpenCV中是BGR而不是RGBfor (int i = 0; i < row; ++i){uchar *c1 = color1.ptr<uchar>(i);uchar *c2 = color2.ptr<uchar>(i);uchar *c3 = color3.ptr<uchar>(i);uchar *r = temp.ptr<uchar>(i);uchar *m = mask.ptr<uchar>(i);for (int j = 0; j < col; ++j){if (m[j] == 255){if (r[j] > (3 * 255 / 4) && r[j] <= 255){c1[j] = 255;c2[j] = 4 * (255 - r[j]);c3[j] = 0;}else if (r[j] <= (3 * 255 / 4) && r[j] > (255 / 2)){c1[j] = 255 - 4 * (3 * 255 / 4 - r[j]);c2[j] = 255;c3[j] = 0;}else if (r[j] <= (255 / 2) && r[j] > (255 / 4)){c1[j] = 0;c2[j] = 255;c3[j] = 4 * (255 / 2 - r[j]);}else if (r[j] <= (255 / 4) && r[j] >= 0){c1[j] = 0;c2[j] = 255 - 4 * (255 / 4 - r[j]);c3[j] = 255;}else {c1[j] = 0;c2[j] = 0;c3[j] = 0;}}}}// 三通道合并,得到颜色图vector<cv::Mat> images;images.push_back(color3);images.push_back(color2);images.push_back(color1);cv::merge(images, result);return result;
}

C++测试代码

#include<iostream>
#include<opencv2/opencv.hpp>
#include<ctime>
using namespace std;
using namespace cv;
void UnitPolar(int squaresize, cv::Mat& mag,cv::Mat& ang);
void UnitCart(int squaresize, cv::Mat& x, cv::Mat& y);
cv::Mat GrayToColor(cv::Mat &phase);
int main(void)
{cv::Mat mag, ang,result,result3;UnitPolar(2001, mag, ang);mag.at<float>(10, 10) = nan("");clock_t start, end;start = clock();result= GrayToColor(mag);end = clock();double diff = end - start;cout << "time:" << diff/ CLOCKS_PER_SEC << endl;system("pause");return 0;
}
void UnitPolar(int squaresize, cv::Mat& mag,cv::Mat& ang) {cv::Mat x;cv::Mat y;UnitCart(squaresize, x, y);                //产生指定范围内的指定数量点数,相邻数据跨度相同// OpenCV自带的转换有精度限制,导致结果有一定差异性//cv::cartToPolar(x, y, mag, ang, false); //坐标转换mag = cv::Mat(x.size(), x.type());ang = cv::Mat(x.size(), x.type());int row = mag.rows;int col = mag.cols;float *m, *a, *xx, *yy;for (int i = 0; i < row; ++i){m = mag.ptr<float>(i);a = ang.ptr<float>(i);xx = x.ptr<float>(i);yy = y.ptr<float>(i);for (int j = 0; j < col; ++j){m[j] = sqrt(xx[j] * xx[j] + yy[j] * yy[j]);a[j] = atan2(yy[j], xx[j]);}}
}void UnitCart(int squaresize, cv::Mat& x, cv::Mat& y) {CV_Assert(squaresize % 2 == 1);x.create(squaresize, squaresize, CV_32FC1);y.create(squaresize, squaresize, CV_32FC1);//设置边界x.col(0).setTo(-1.0);x.col(squaresize - 1).setTo(1.0f);y.row(0).setTo(1.0);y.row(squaresize - 1).setTo(-1.0f);float delta = 2.0f / (squaresize - 1.0f);  //两个元素的间隔//计算其他位置的值for (int i = 1; i < squaresize - 1; ++i) {x.col(i) = -1.0f + i * delta;y.row(i) = 1.0f - i * delta;}
}/*** @brief GrayToColor                      灰度图上色* @param phase                            输入的灰色图像,通道为1* @return                                 上色后的图像*/
static cv::Mat GrayToColor(cv::Mat &phase)
{CV_Assert(phase.channels() == 1);cv::Mat temp, result, mask;// 将灰度图重新归一化至0-255cv::normalize(phase, temp, 255, 0, cv::NORM_MINMAX);temp.convertTo(temp, CV_8UC1);// 创建掩膜,目的是为了隔离nan值的干扰mask = cv::Mat::zeros(phase.size(), CV_8UC1);mask.setTo(255, phase == phase);// 初始化三通道颜色图cv::Mat color1, color2, color3;color1 = cv::Mat::zeros(temp.size(), temp.type());color2 = cv::Mat::zeros(temp.size(), temp.type());color3 = cv::Mat::zeros(temp.size(), temp.type());int row = phase.rows;int col = phase.cols;// 基于灰度图的灰度层级,给其上色,最底的灰度值0为蓝色(255,0,0),最高的灰度值255为红色(0,0,255),中间的灰度值127为绿色(0,255,0)// 不要惊讶蓝色为什么是(255,0,0),因为OpenCV中是BGR而不是RGBfor (int i = 0; i < row; ++i){uchar *c1 = color1.ptr<uchar>(i);uchar *c2 = color2.ptr<uchar>(i);uchar *c3 = color3.ptr<uchar>(i);uchar *r = temp.ptr<uchar>(i);uchar *m = mask.ptr<uchar>(i);for (int j = 0; j < col; ++j){if (m[j] == 255){if (r[j] > (3 * 255 / 4) && r[j] <= 255){c1[j] = 255;c2[j] = 4 * (255 - r[j]);c3[j] = 0;}else if (r[j] <= (3 * 255 / 4) && r[j] > (255 / 2)){c1[j] = 255 - 4 * (3 * 255 / 4 - r[j]);c2[j] = 255;c3[j] = 0;}else if (r[j] <= (255 / 2) && r[j] > (255 / 4)){c1[j] = 0;c2[j] = 255;c3[j] = 4 * (255 / 2 - r[j]);}else if (r[j] <= (255 / 4) && r[j] >= 0){c1[j] = 0;c2[j] = 255 - 4 * (255 / 4 - r[j]);c3[j] = 255;}else {c1[j] = 0;c2[j] = 0;c3[j] = 0;}}}}// 三通道合并,得到颜色图vector<cv::Mat> images;images.push_back(color3);images.push_back(color2);images.push_back(color1);cv::merge(images, result);return result;
}

测试效果

图1 灰度图
图2 颜色图

       如上图所示,为了方便,我生成了一个2001*2001的图像矩阵,图1为灰度图,图2是经过颜色处理后的颜色图,满足了前面提到的需求。

       如果函数有什么可以改进完善的地方,非常欢迎大家指出,一同进步何乐而不为呢~

       如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!


http://chatgpt.dhexx.cn/article/Iy8NAWTk.shtml

相关文章

灰度图与二值化

图像处理的灰度化和二值化 在图像处理中&#xff0c;用RGB三个分量&#xff08;R&#xff1a;Red&#xff0c;G&#xff1a;Green&#xff0c;B&#xff1a;Blue&#xff09;&#xff0c;即红、绿、蓝三原色来表示真彩色&#xff0c;R分量&#xff0c;G分量&#xff0c;B分量的…

opencv学习5:cvtColor RGB图像转灰度图像原理

简介 将彩色图像转化成为灰度图像的过程成为图像的灰度化处理。彩色图像中的每个像素的颜色有R、G、B三个分量决定&#xff0c;而每个分量有255中值可取&#xff0c;这样一个像素点可以有1600多万&#xff08;255*255*255&#xff09;的颜色的变化范围。而灰度图像是R、G、…

Matplotlib显示灰度图

引言 matplotlib中的imshow()函数不能自动显示灰度图像&#xff0c;这一点应该是众所周知的&#xff0c;需要调用cmap“gray"以进行设置&#xff0c;但是cmap"gray"实际上并不是如opencv中的imshow函数一样将单通道图显示为灰度图&#xff0c;私以为是引入了灰度…

python显示灰度图像,Python读取图像并显示灰度图的实现

python读取图像 原图: import cv2 # 利用opencv读取图像 import numpy as np # 利用matplotlib显示图像 import matplotlib.pyplot as plt img cv2.imread("./lena.png") #读取图像 # 显示图像 plt.imshow(img) plt.axis(off) plt.show() 效果&#xff1a; 问&#…

OpenCV灰度图

什么是灰度图&#xff1a; 百度百科 什么是灰度图 #include <opencv2/opencv.hpp> #include <iostream>using namespace cv; using namespace std;int main(int argc, char** argv) {Mat src Mat(4,4,CV_8UC3,Scalar(28,128,228));cout << src << en…

RGB图像转化为灰度图原理

RGB图像转化为灰度图原理 1 原理 利用MATLAB对RGB图像进行读取&#xff1a; imgimread(蒙娜丽莎.jpg);可以知道存储RGB图像数据为 256 256 3 u i n t 8 256\times256 \times3\quad uint8 2562563uint8&#xff0c;其中 256 256 256\times256 256256表示长和宽的像素个数&…

彩色图像转换灰度图像

数字图像 现在我们所接触到的图像绝大多数都是数字图像&#xff0c;图像数字化后&#xff0c;每个像素点就可以看作是一个小方格&#xff0c;每个小方格里面存储的就是图像的像素信息。如果把一副数字图像抽象出来&#xff0c;就是一个二维矩阵&#xff08;灰度图&#xff09;或…

Python灰度图像彩色化

1️⃣作业要求 给定一幅灰度图像&#xff0c;使用任意方法将其变成一幅彩色图像&#xff0c;并尽量使得添加的色彩显得较为真实。 2️⃣核心代码 这里我们是直接调用了eccv16和siggraph17的模型&#xff0c;运行程序时会自动下载这两个model文件&#xff0c;然后经过对图像的…

matlab 绘制灰度图

matlab 将矩阵中不同数值所对应的区域用 不同深度的灰度图画出来&#xff0c;不显示坐标轴标签&#xff0c;并设置在画布上全屏显示。 if 1close allrng (7)mask_allrand(256,256)*10;mask_allround(mod(mask_all,2));mask_allsort(mask_all);mask_all(1:100,1:50)0;mask_all(…

matlab读取一幅灰度图,Matlab处理灰度图

作业2&#xff1a;通过图像分析的方法对如下图像进行分析&#xff0c;获取颗粒特性参数。具体参数包括图像中的颗粒个数&#xff0c;颗粒面积&#xff0c;颗粒等效直径&#xff0c;非球形颗粒的长/短轴&#xff0c;非球形颗粒的方位。 图1 待处理颗粒图像 步骤&#xff1a; (1)…

python灰度图

任务描述 背景   真彩色图像和灰度图像是数字图像的两种常见类型&#xff0c;如下图所示&#xff0c;左图是真彩色图像&#xff0c;右图是灰度图像。    在真彩色图像中&#xff0c;像素颜色是 RGB 颜色&#xff0c;每个颜色包含 R、G、B 三个颜色分量。而在灰度图像中&…

图像处理--灰度图

灰度图 灰度图&#xff0c;Gray Scale Image 或是Grey Scale Image&#xff0c;又称灰阶图。把白色与黑色之间按对数关系分为若干等级&#xff0c;称为灰度。灰度分为256阶。 灰度图定义 什么叫灰度图&#xff1f;任何颜色都有红、绿、蓝三原色组成&#xff0c;假如原来某点…

OpenCV(三)彩色图灰度化、通道分离、单通道反差处理(灰度图)、多通道反差处理(彩色图)

目录 一、彩色图灰度化 1、主要函数cvtColor()介绍 2、代码 3、效果 二、通道分离 1、向量介绍 2、总代码 3、效果 三、单通道(灰度图)反差处理 1、单通道向量访问 2、代码 3、效果 四、多通道(彩色图)反差处理&#xff08;彩色图的反差处理&#xff09; 1、多…

灰度图与RGB图

1.灰度图 灰度图就是单通道图像&#xff0c;而单通道图是指维度数为2的图像。 而灰度就是没有色彩&#xff0c;RGB色彩分量全部相等&#xff08;可将这点与下文的RGB图进行对比&#xff09;。那么灰度图的每个像素点就只有一个值表示颜色&#xff0c;像素值的范围就是[0~255]。…

ER图、ERD图

ER图、ERD图 1. 什么是ERD1.1 举例 2. ERD符号指南2.1 实体2.2 属性2.3 主键2.4 外键2.4 关系2.5 基数2.5.1 一对一的基数的例子2.5.2 一对多的基数的例子2.5.3 多对多的基数的例子 3.概念、逻辑和物理数据模型3.1 概念数据模型3.2 逻辑数据模型3.3 物理数据模型 4.如何绘制ER图…

2.2.2 ER图

2.2.2 ER图 关系型数据库提供了SQL语言&#xff0c;使应用程序开发人员与数据库管理和维护人员能够与数据库进行交互。但是在创建数据库和数据表之前&#xff0c;需要对数据库中的数据表进行设计&#xff0c;并能够正确设计出各数据表之间的关联关系。 通常使用ER图&#xf…

【系统架构】ER图的画图规范和优化点

文章目录 什么是ER图ER图的画图规范组成部分步骤注意 实例 第三弹&#xff0c;讲讲ER图的画图规范以及优化点 什么是ER图 E-R图也称实体-联系图(Entity Relationship Diagram)&#xff0c;提供了表示实体类型、属性和联系的方法&#xff0c;用来描述现实世界的概念模型 ER图…

学好er图

一、什么是er图&#xff1f; ​ 1、 实体-联系图(Entity-Relation Diagram)用来建立数据模型,在数据库系统概论中属于概念设计阶段&#xff0c;形成一个独立于机器&#xff0c;独立于DBMS的ER图模型。 通常将它简称为ER图&#xff0c;相应地可把用ER图描绘的数据模型称为ER模型…

ER图学习笔记(附各个图型的举例,实战案例)

ER图常用图形如下&#xff1a; ER图图形含义详解 实体&#xff08;长方体&#xff09;&#xff1a; 实体字面意思就是实际存在的&#xff0c;例如商品&#xff0c;货物&#xff0c;用户。 属性&#xff08;椭圆&#xff09;&#xff1a; 属性我们不陌生&#xff0c;就是一个…

enterprise architect绘画ER图

ER图的实体&#xff08;entity&#xff09;即数据模型中的数据对象&#xff0c;例如人、学生、音乐都可以作为一个数据对象&#xff0c;用长方体来表示&#xff0c;每个实体都有自己的实体成员&#xff08;entity member&#xff09;或者说实体对象&#xff08;entity instance…