图片颜色处理

news2024/11/19 9:25:17

目录

  • 背景
    • 任务需求
    • 思考过程

背景

背景叙述的是我为什么要做颜色处理以及整个思考过程,有些流水账,可不看。

任务需求

拍照,获取图片中固定一块区域的颜色,判断是不是红色。

思考过程

知道这个任务的时候,首先对图像处理不熟悉,没做过,第二,任务需求比较模糊。
然后我了解到拍照出来的图像格式为rgb565,那么我需要拿到某一块区域的颜色,我就需要去了解rgb565图片格式,一个像素占几个字节,能取到想要的范围后发现,我这一片区域需要取哪个颜色?这时候我了解到了两个滤波算法,分别是中值滤波和均值滤波。

这时候遇到了一个问题,我对一片区域做中值滤波或者均值滤波,假设这片区域需要滤波9个像素点,那么滤波涉及到的像素点就是5*5 = 25个像素点,那么滤波到后面,肯定包含之前滤波后的像素点,那么这时候使用的值是使用滤波前的还是滤波后的。说的比较绕,如下图所示
下图为滤波前的,红色框代表的是需要滤波的像素点。
在这里插入图片描述
下图为红框第一位也就是63中值滤波后为52,那么准备第二位滤波也就是21滤波,我该拿的是63还是拿52,63代表的是滤波前的,52代表是滤波后的基础上滤波的。我查了半天没找到哪里有依据,我师傅告诉我说是拿滤波前也就是63再滤波。
在这里插入图片描述
为什么两种滤波,我选择了中值滤波没选择均值滤波?
这时候我去了解了一下这两种滤波方式的区别以及优缺点。
我选择使用中值滤波是因为如果使用均值滤波的话,我需要滤波的一片像素有一部分噪声,那么就会导致均值滤波出来的颜色跟肉眼看这一片区域的颜色差别很大,中值滤波就不会。

这时候我拿到了我想要的rgb数据,我发现我需要与哪个颜色数据对比,因为不同的饱和度和亮度啥的都会导致每次拿的数据不一样,那我怎么进行颜色比较?然后我首先想到的是不是有个范围,那么这个范围是多少,如何定义的?

这时候一直百度,以及询问别人,了解到了一个色差的概念,经过百度色差相关的知识了解到了hsv,那么rgb565如何转成hsv?百度了一下有相关文章有写。然后对比两个颜色的hsv,就会出来一个数值,那么这个数值设定多少才算是肉眼看上去是同一个颜色?经过了百度以及测试,我赶紧差值在3.5左右是可以接收的。

下面贴的代码主要就是RGB565和RGB888之间的转换,RGB888转换成HSV,以及色差比较的代码。

两个滤波算法代码就没贴上了,百度挺多的。

#include "stdio.h"
#include "stdint.h"
#include "math.h"

#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max3(a, b, c) (((a) > (b) ? (a) : (b)) > (c) ? ((a) > (b) ? (a) : (b)) : (c))
#define min3(a, b, c) (((a) < (b) ? (a) : (b)) < (c) ? ((a) < (b) ? (a) : (b)) : (c))

typedef struct
{
    uint16_t r;
    uint16_t g;
    uint16_t b;
    uint32_t color;
} color_rgb_t;
typedef struct
{
    double h;
    double s;
    double v;
} color_hsv_t;

/*********************************************************************************************
RGB转化到HSV的算法:
    max=max(R,G,B);
    min=min(R,G,B);
    V=max(R,G,B);
    S=(max-min)/max;
    if (R = max) H =(G-B)/(max-min)* 60;
    if (G = max) H = 120+(B-R)/(max-min)* 60;
    if (B = max) H = 240 +(R-G)/(max-min)* 60;
    if (H < 0) H = H + 360;
***********************************************************************************************/

/**
 * @brief   RGB颜色空间 转  HSV颜色空间
 * @param   rgb:RGB颜色空间参数
 * @param   hsv:HSV颜色空间参数
 * @note    The R,G,B values are divided by 255 to change the range from 0..255 to 0..1:
 * @return  none
 */
void rgb2hsv(color_rgb_t *rgb, color_hsv_t *hsv)
{
    float max, min, delta = 0;
    float r = (float)((float)((int)rgb->r) / 255);
    float g = (float)((float)((int)rgb->g) / 255);
    float b = (float)((float)((int)rgb->b) / 255);

    max = max3(r, g, b);
    min = min3(r, g, b);
    // printf("rgb2hsv max = %d,min = %d\n", max, min);
    delta = (max - min);

    // printf("r:%f, g:%f, b:%f\n", r, g, b);

    if (delta == 0)
    {
        hsv->h = 0;
    }
    else
    {
        if /**/ (r == max)
        {
            hsv->h = ((g - b) / delta) * 60;
        }
        else if (g == max)
        {
            hsv->h = 120 + (((b - r) / delta) * 60);
        }
        else if (b == max)
        {
            hsv->h = 240 + (((r - g) / delta) * 60);
        }

        if (hsv->h < 0)
        {
            hsv->h += 360;
        }
    }

    if (max == 0)
    {
        hsv->s = 0;
    }
    else
    {
        hsv->s = (float)(delta / max);
    }

    hsv->v = max;

    // printf("rgb2hsv HSV,H:%lf,S:%lf,V:%lf\n", hsv->h, hsv->s, hsv->v);

    rgb->color = (unsigned int)(((rgb->r & 0xff) << 16) | ((rgb->g & 0xff) << 8) | (rgb->b & 0xff));
    printf("color:%x,r:%x,g:%x,b:%x",rgb->r,rgb->g,rgb->b);
}

double HSVDistance(color_hsv_t *hsv_1, color_hsv_t *hsv_2)
{
    double H_1 = hsv_1->h;
    double S_1 = hsv_1->s;
    double V_1 = hsv_1->v;
    double H_2 = hsv_2->h;
    double S_2 = hsv_2->s;
    double V_2 = hsv_2->v;

    double R = 100;
    double angle = 30;

    double h = R * cos(angle / 180 * M_PI);
    double r = R * sin(angle / 180 * M_PI);

    double x1 = r * V_1 * S_1 * cos(H_1 / 180 * M_PI);
    double y1 = r * V_1 * S_1 * sin(H_1 / 180 * M_PI);
    double z1 = h * (1 - V_1);

    double x2 = r * V_2 * S_2 * cos(H_2 / 180 * M_PI);
    double y2 = r * V_2 * S_2 * sin(H_2 / 180 * M_PI);
    double z2 = h * (1 - V_2);

    double dx = x1 - x2;
    double dy = y1 - y2;
    double dz = z1 - z2;

    return sqrt(dx * dx + dy * dy + dz * dz);
}

#define RGB888_RED 0x00ff0000
#define RGB888_GREEN 0x0000ff00
#define RGB888_BLUE 0x000000ff

#define RGB565_RED 0xf800
#define RGB565_GREEN 0x07e0
#define RGB565_BLUE 0x001f

unsigned short RGB888ToRGB565(unsigned int n888Color)
{
    unsigned short n565Color = 0;

    unsigned char cRed = (n888Color & RGB888_RED) >> 19;
    unsigned char cGreen = (n888Color & RGB888_GREEN) >> 10;
    unsigned char cBlue = (n888Color & RGB888_BLUE) >> 3;

    n565Color = (cRed << 11) + (cGreen << 5) + (cBlue << 0);
    return n565Color;
}

unsigned int RGB565ToRGB888(unsigned short n565Color)
{
    unsigned int n888Color = 0;

    unsigned char cRed = (n565Color & RGB565_RED) >> 8;
    unsigned char cGreen = (n565Color & RGB565_GREEN) >> 3;
    unsigned char cBlue = (n565Color & RGB565_BLUE) << 3;

    n888Color = (cRed << 16) + (cGreen << 8) + (cBlue << 0);
    return n888Color;
}

int main()
{
    // double hsv_1;
    // double hsv_2;

    color_rgb_t rgb_1 = {
        .r = 117,
        .g = 137,
        .b = 44,
    };
    color_rgb_t rgb_2 = {
        .r = 186,
        .g = 203,
        .b = 187,
    };

    color_hsv_t hsv_1;
    color_hsv_t hsv_2;

    rgb2hsv(&rgb_1, &hsv_1);
    rgb2hsv(&rgb_2, &hsv_2);

    printf("RGB,R:%d,G:%d,B:%d,COLOR:0X%x\n", rgb_1.r, rgb_1.g, rgb_1.b, rgb_1.color);
    printf("HSV,H:%lf,S:%lf,V:%lf\n", hsv_1.h, hsv_1.s, hsv_1.v);

    printf("=======================================\n");
    printf("HSV distance:%lf\n", HSVDistance(&hsv_1, &hsv_2));

    return 0;
}

参考文章:HSV颜色空间和RGB颜色空间相互转换C语言实现

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

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

相关文章

深入理解Self-attention

概述 输入的特点 是一个向量序列序列的长度是可变的例如&#xff1a;对于音频数据&#xff0c;STFT之后&#xff0c;得到每个帧的特征&#xff0c;这些帧在时间维度上构成序列 输出类型有三种 对序列中的每一个向量&#xff0c;都有一个对应的输出&#xff0c;比如说要对一段…

活动星投票国潮大秀东方网络评选投票怎么做的免费微信投票活动

如果通过一个小程序免费制作一个微信投票活动呢&#xff1f;文章详细讲解如何利用一款免费好用的微信小程序“活动星投票”小程序来制作投票活动&#xff0c;无需注册即可免费制作&#xff0c;非常的方便快捷&#xff0c;可以实现视频投票、分组投票、隐藏选手票数、导出投票数…

Feign作为HTTP客户端调用远程服务

前言 在分布式微服务的机构体系下&#xff0c;我们日常开发调用内部微服务的方式通常是Feign调用&#xff0c;grpc、dubbo&#xff0c;大部分的公司后端架构基本是以Spring Cloud 体系下的&#xff0c;所以基本会用到Feign&#xff0c;Feign是 Netflix开发的声明式、模板化的H…

基于jeecgboot的flowable流程支持定时边界事件

Flowable事件 事件&#xff08;event&#xff09;通常用于为流程生命周期中发生的事情建模。事件总是图形化为圆圈。在BPMN 2.0中&#xff0c;有两种主要的事件分类&#xff1a;*捕获&#xff08;catching&#xff09;与抛出&#xff08;throwing&#xff09;*事件。 捕获: 当…

【Linux】——权限理解

目录 1.Linux权限的概念 Linux权限管理 1.文件访问者的分类&#xff08;人的属性&#xff09; 2.文件类型和访问权限&#xff08;事物属性&#xff09; 2.1文件类型 2.2基本权限 2.3文件权限值的表示方法 2.4文件访问权限的相关设置方法 file指令 目录的权限 默认权限…

2000-2019年省级农业绿色全要素生产率原始测算数据和结果数据

2000-2019年省级农业绿色全要素生产率原始测算数据和结果数据 1、时间&#xff1a;2000-2019年 2、范围&#xff1a;包括30个省份 3、方法&#xff1a;使用的方法为SBM-GML指数、SBM-BML指数、SBM-ML指数和全局SBM&#xff08;静态&#xff09;。 同时&#xff0c;还提供了…

抗反射蛾眼结构的严格分析与设计

摘要 对于许多光学应用来说需要减少表面反射。控制表面反射的一种非常有效的方法是使用抗反射的纳米或微米结构&#xff0c;启发来源于自然界&#xff08;蛾眼&#xff09;。这些具有亚波长范围特征尺寸的结构表现出关于波长和角度依赖性的独特性质。在本文中&#xff0c;介绍了…

SSM校园报修系统

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a; 1、学生功能&#xff1a; (1)学生登录&#xff1a;学生通过管理员下发的初始账号和密码&#xff0c;可以登录系统进行申…

git diff 命令6种使用场景

目录 一、背景&目标 二、git三个区了解 三、git diff 6种场景介绍 3.1 工作区和暂存区差异对比 3.2 工作区和版本库之间差异 3.3 暂存区和版本库之间差异对比 3.4 本地版本库之间提交记录对比 3.5 不同分支对比 3.6 不同分支下同一文件对比 四、git diff 中 -x1,y…

非零基础自学Golang 第12章 接口与类型 12.3 接口嵌入

非零基础自学Golang 文章目录非零基础自学Golang第12章 接口与类型12.3 接口嵌入第12章 接口与类型 12.3 接口嵌入 接口嵌入&#xff0c;也叫接口组合&#xff0c;在其他语言中&#xff0c;这种接口的组合叫作继承&#xff1b;Go语言舍弃了繁杂的继承体系&#xff0c;但继承这…

48页智慧城市大数据可视化平台建设方案

目 录 1. 概述 1.1 需求分析 1.2 采取策略 1.3 方案目标 2. 智慧城市解决方案 2.1 架构说明 2.1.1 整体架构 2.1.2 规划架构 2.1.3 云平台架构 2.2 建设内容 2.2.1 云计算公共支撑平台 2.2.2 智慧规划 2.2.3 智慧管网 2.2.4 智能政务 2.2.5 智慧交通 2.2.6 智慧…

两台笔记本之间快速传输文件,两台电脑之间快速传输大量文件

想用自己的笔记本电脑给同事的电脑传文件&#xff0c;却发现自己和同事都没有带U盘和数据线&#xff0c;怎么办&#xff1f;两台笔记本之间快速传输文件&#xff1f;接下来介绍的方法你可能用得到。 方案一、微信、QQ传输文件 简单的方法就是两台电脑都登陆聊天工具&#xff0…

小学生C++编程基础 课程7(B)

904.等差数列 (课程7) 登录 905.双等差数列 (课程7) 登录 906.打印数列1 (课程7) 登录 907.打印数列2 (课程7) 难度&#xff1a;1 登录 908.对称数列 (课程7) 登录 909.个位数是7 &#xff08;课程7&#xff09; 登录 910.打印数列3 &#xff08;课程7&#xff09; 登录…

【AI理论学习】n-gram语言模型和神经网络语言模型

n-gram语言模型和神经网络语言模型什么是语言模型语言模型的计算什么是n-gram模型n-gram平滑技术什么是神经网络语言模型&#xff08;NNLM&#xff09;&#xff1f;基于前馈神经网络的模型基于循环神经网络的模型语言模型评价指标总结参考资料什么是语言模型 语言模型是自然语…

重磅!张文宏最新防治指南来了!

文 | 闲欢来源&#xff1a;Python 技术「ID: pythonall」最近全国各地最热门的话题恐怕都是跟“羊”有关的了。混乱时期两周之前&#xff0c;在所有人猝不及防的情况下&#xff0c;国家宣布放开疫情防控。从此我们再也不用每天排队做核酸&#xff0c;上班或者出去完也不用处处设…

二维Poisson方程五点差分格式与Python实现

最近没怎么写新文章&#xff0c;主要在学抽象代数下学期还有凸分析好累的一学期哦对&#xff0c;我不是数学系的&#xff0c;我是物理系的。而且博主需要澄清一下&#xff0c;博主没有对象&#xff0c;至少现在还没有。好&#xff0c;兄弟们&#xff0c;好习惯&#xff0c;先上…

SSM鹊巢大连分公司分销商管理系统

开发工具(eclipse/idea/vscode等)&#xff1a;idea 数据库(sqlite/mysql/sqlserver等)&#xff1a;mysql 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a;、主要功能 一、&#xff1a;人员管理&#xff1a;自己派遣到各个地区的员工&#xff0c;也就是分销商&#xf…

Java平衡树之红黑树代码实现过程详解(2)

红黑树 前面介绍了2-3树&#xff0c;可以看到2-3树能保证在插入元素之后&#xff0c;树依然保持平衡状态&#xff0c;它的最坏情况下所有子结点都是2-结点&#xff0c;树的高度为lgN,相比于我们普通的二叉查找树&#xff0c;最坏情况下树的高度为N&#xff0c;确实保证了最坏情…

药学专业转行软件测试,真的可以月薪过万吗?

转行原因 我在大学里学的是药学专业&#xff0c;毕业之后也顺利从事了对口的工作——药物分析。工作很稳定&#xff0c;但是内容很繁琐&#xff0c;薪资也一般&#xff0c;但从我自己内心来说从来没有开心过&#xff0c;因为我不想从事这样枯草并且一眼就可以看到老的人生。 …

常见的DDoS攻击方式和预防方法

DDoS攻击指分布式拒绝服务攻击&#xff0c;即处于不同位置的多个攻击者同时向一个或数个目标发动攻击&#xff0c;或者一个攻击者控制了位于不同位置的多台机器并利用这些机器对受害者同时实施攻击。以下是三种常见的DDoS攻击方式&#xff1a; 1.TCP洪水攻击&#xff08;SYN …