opencv 实线PS色阶调整
#include <opencv2/opencv.hpp>#include <iostream>using namespace cv;class Level {public:intShadow;//输入色阶黑点值float Midtones; //输入色阶灰点值(注意是浮点数)intHighlight; //输入色阶白点值intOutputShadow; //输出色阶黑点值
·
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
class Level {
public:
int Shadow; //输入色阶黑点值
float Midtones; //输入色阶灰点值(注意是浮点数)
int Highlight; //输入色阶白点值
int OutputShadow; //输出色阶黑点值
int OutputHighlight; //输出色阶白点值
Level() {};
virtual ~Level() {};
bool createColorTable(uchar* colorTable)
{
int diff = (int)(Highlight - Shadow);
int outDiff = (int)(OutputHighlight - OutputShadow);
if (!((Highlight <= 255 && diff <= 255 && diff >= 2) ||
(OutputShadow <= 255 && OutputHighlight <= 255 && outDiff < 255) ||
(!(Midtones > 9.99 && Midtones > 0.1) && Midtones != 1.0)))
return false;
double coef = 255.0 / diff;
double outCoef = outDiff / 255.0;
double exponent = 1.0 / Midtones;
for (int i = 0; i < 256; i++)
{
int v;
// calculate black field and white field of input level
if (colorTable[i] <= (uchar)Shadow) {
v = 0;
}
else {
v = (int)((colorTable[i] - Shadow) * coef + 0.5);
if (v > 255) v = 255;
}
// calculate midtone field of input level
v = (int)(pow(v / 255.0, exponent) * 255.0 + 0.5);
// calculate output level
colorTable[i] = (uchar)(v * outCoef + OutputShadow + 0.5);
}
return true;
}
};
class Levels {
protected:
bool createColorTables(uchar colorTables[][256])
{
bool result = false;
int i, j;
//initialize color table
for (i = 0; i < 3; i++) {
for (j = 0; j < 256; j++)
colorTables[i][j] = (uchar)j;
}
//create color table for each channel
//result = BlueChannel.createColorTable(colorTables[0]);
//result = GreenChannel.createColorTable(colorTables[1]);
//result = RedChannel.createColorTable(colorTables[2]);
result = RGBChannel.createColorTable(colorTables[0]);
result = RGBChannel.createColorTable(colorTables[1]);
result = RGBChannel.createColorTable(colorTables[2]);
return result;
}
public:
Level RGBChannel; //RGB整体调整
//Level RedChannel; //红色通道
//Level GreenChannel; //绿色通道
//Level BlueChannel; //蓝色通道
Levels() {};
virtual ~Levels() {};
//实施色阶调整
int adjust(InputArray src, OutputArray dst)
{
Mat input = src.getMat();
if (input.empty()) {
return -1;
}
dst.create(src.size(), src.type());
Mat output = dst.getMat();
const uchar* in;
uchar* out;
int width = input.cols;
int height = input.rows;
int channels = input.channels();
uchar colorTables[3][256];
//create color tables
if (!createColorTables(colorTables)) {
//error create color table"
return 1;
}
//adjust each pixel
#ifdef HAVE_OPENMP
#pragma omp parallel for
#endif
for (int y = 0; y < height; y++) {
in = input.ptr<uchar>(y);
out = output.ptr<uchar>(y);
for (int x = 0; x < width; x++) {
for (int c = 0; c < 3; c++) {
*out++ = colorTables[c][*in++];
}
for (int c = 0; c < channels - 3; c++) {
*out++ = *in++;
}
}
}
return 0;
}
};
void colorClassAdjust(Mat img, Mat& dst, int shadow = 202, int midtones = 100, int highlight = 255);
int main()
{
Mat src;
//src = imread("E:\\photo\\xuxian.jpg");
/*if (!src.data)
{
std::cout << "error read image" << std::endl;
return -1;
}*/
VideoCapture capture("G:\\shared\\CarShowRecorder1\\RecordVideo3\\CARSHOW_VID_20210830_145444.mp4"); //改用自己的视频地址
if (!capture.isOpened())
{
std::cout << "no pic..." << std::endl;
return -1;
}
namedWindow("src", 1);
//Levels levels;
//Level* currentChannel = NULL;
//currentChannel = &levels.RGBChannel;
//if (currentChannel == NULL)
// return -1;
//// 给色阶的黑点、白点、灰度赋值
//int Shadow = 210;
//int Midtones = 100;
//int Highlight = 255;
//int OutputShadow = 0;
//int OutputHighlight = 255;
//currentChannel->Shadow = Shadow;
//currentChannel->Midtones = Midtones / 100.0;
//currentChannel->Highlight = Highlight;
//currentChannel->OutputShadow = OutputShadow;
//currentChannel->OutputHighlight = OutputHighlight;
for (;;)
{
capture.read(src);
imshow("src", src);
Mat dst;
//levels.adjust(src, dst);
colorClassAdjust(src, dst);
imshow("dst", dst);
if (waitKey(30) > 0)
break;
}
waitKey(0);
return 0;
}
void colorClassAdjust(Mat img, Mat& dst, int shadow, int midtones, int highlight)
{
Levels levels;
Level* currentChannel = NULL;
currentChannel = &levels.RGBChannel;
if (currentChannel == NULL)
return ;
// 给色阶的黑点、白点、灰度赋值
//int Shadow = 210;
//int Midtones = 100;
//int Highlight = 255;
//int OutputShadow = 0;
//int OutputHighlight = 255;
currentChannel->Shadow = shadow;
currentChannel->Midtones = midtones / 100.0;
currentChannel->Highlight = highlight;
currentChannel->OutputShadow = 0;
currentChannel->OutputHighlight = 255;
levels.adjust(img, dst);
}
作用是为了提高每帧图片的对比度,需要注意的是:我已经将整个功能封装到 colorClassAdjust()方法中, 直接调用这个方法就可以, 另外,可以自行修改需要输出的OutputShadow(输出黑点)、OutputHighlight(输出高光)值
具体参数功能作用,代码注释有,如有问题,欢迎留言交流。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)