IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 图片颜色处理 -> 正文阅读

[人工智能]图片颜色处理

背景

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

任务需求

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

思考过程

知道这个任务的时候,首先对图像处理不熟悉,没做过,第二,任务需求比较模糊。
然后我了解到拍照出来的图像格式为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语言实现

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2022-12-25 11:10:20  更:2022-12-25 11:14:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/4 16:46:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码