学更好的别人,
做更好的自己。
——《微卡智享》
本文长度为1035字,预计阅读4分钟
前言
做UI界面时,常常会遇到配色的问题,有专业美工还好,没有的话,你想要什么颜色,需要自己进行提取,如果没有PS,那我们就用OpenCV做个简单的颜色提取功能。
实现效果
实现OpenCV获取颜色提取需要什么?
A
从上面的GIF动图中可以看出来,每点击图像中的位置直接显示出当前的RGB色和转换为16进制的字符。实现这个方式最主要的就考虑几点:
- 鼠标点击事件,获取当前位置
- 获取当前点的R、G、B的值
- 如果从RGB的值中转换为16进制
代码实现
微卡智享
代码语言:javascript复制#pragma once
#include <iostream>
#include <opencv2/opencv.hpp>
#include "../../Utils/CvUtils.h"
using namespace std;
using namespace cv;
Mat src;
Mat srccopy; //用于拷贝出的源图像
string showsrc = "图像";
//鼠标回调函数
void onMouse(int event, int x, int y, int flags, void* ustc);
//RGB颜色转换为HEX
string rgb2hex(int r, int g, int b, bool ishead = false);
int main(int argc, char** argv) {
src = imread("E:/DCIM/6.jpg");
CvUtils::MatResize(src);
CvUtils::SetShowWindow(src, showsrc, 500, 20);
imshow(showsrc, src);
//设置鼠标响影事件
setMouseCallback(showsrc, onMouse);
waitKey(0);
return 0;
}
void onMouse(int event, int x, int y, int flags, void* ustc)
{
//鼠标左键按下
if (event == EVENT_LBUTTONUP)
{
srccopy = src.clone();
//获取点击位置的颜色,此处注意y和x的位置顺序
Scalar color = srccopy.at<Vec3b>(y, x);
int b = color[0];
int g = color[1];
int r = color[2];
string hexstr = rgb2hex(r, g, b, true);
string rgbtext = "RGB(" to_string(r) "," to_string(g) "," to_string(b) ")";
string hextext = "HEX:" hexstr;
//在图像上画出点击位置
circle(srccopy, Point(x, y), 2, Scalar(0, 255, 255));
//输出显示文字
putText(srccopy, rgbtext, Point(x 5, y 5), 1, 1.2, Scalar(0, 255, 255));
putText(srccopy, hextext, Point(x 5, y 35), 1, 1.2, Scalar(0, 255, 255));
imshow(showsrc, srccopy);
}
}
string rgb2hex(int r, int g, int b, bool ishead)
{
stringstream hexstr;
if (ishead) hexstr << "#";
hexstr << hex << (r << 16 | g << 8 | b);
cout << "rgb:" << r << "," << g << "," << b << " hex:" << hexstr.str() << endl;
return hexstr.str();
}
微卡智享
划重点
在鼠标事件中获取图像当前点颜色时,一定要记录第一个参数是y,第二个参数是x,在OpenCV中参数一般说是row和col的概念,row是行代表是y轴,col是列代表是x轴。
代码中CvUtils的图片调整大小的显示位置,在当时写的CvUtils中实现,整个小Demo也是在我的OpenCVDemoCPP中,可以直接下载那个源码,里面还有别的Demo练习。
从RGB转Hex直接在C 中std::hex中实现即可,比较简单。这样一个OpenCV的颜色提取小Demo就完成了。
源码地址
https://github.com/Vaccae/OpenCVDemoCpp.git