对下面文章的技术验证,代码升级
引用:[1] bloom特效 - 星光下的守望者 - 博客园
网友的Bloom文章,这里进行试验,改造为新版本的OpenCV代码
测试运行环境
- OpenCV 4.4.0
- MinGW 编译
- VSCode 1.5.1
- 时间:2020-10
一、简述理论
RGB转为YUV,Y为亮度,详细见引用的博文。
Y=0.299R+0.587G+0.114B;
U=-0.147R-0.289G+0.436B;
V=0.615R-0.515G-0.100B;
步骤:
1 读入原图
chinesedragon.jpg放到exe相同的目录下,使用imread读取图像
2. 转为灰度图
使用cvtColor函数进行灰度转换,传入COLOR_BGR2GRAY参数
使用clone
3. 阀值控制
使用 img.clone()来克隆一份数据,防止对原来数据修改。
可以写代码来处理见本程序,也可以使用函数,如:
cv::threshold(imggrey, imggrey1, 170, 255, cv::THRESH_BINARY);
然后根据imggrey1去处理img
4. 高斯均匀化
可以使用GaussianBlur函数进行高斯均匀化。控制 ks的大小,比如ks(20, 20) 可以扩大均匀效果,也可以修改Sigma参数来调整
5. 合并相加
通过加权平均方法,把两个图片相加。
二、程序改造
原来的代码不是OpenCV 3 、4的格式。
下面修改为新版本的格式:
大致修改函数等:
- IplImage 改为mat类型
- cvLoadImage 改为imread
- cvNamedWindow 改为namedWindow
- CV_WINDOW_AUTOSIZE=>WINDOW_AUTOSIZE
- 显示原jpg图,cvShowImage =》imshow
- CV_BGR2GRAY=> COLOR_BGR2GRAY
- cvPtr2D 改为blur.ptr
代码如下(示例):
/*
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
#define THRESHOLD_COLOR 0x38 //阀值,可以为0
#define A_VALUE 1.0f //原图的系数
#define B_VALUE 1.0f //新图的系数
Mat img; //IplImage 改为mat类型
/**
@brief Main函数
@param argc 参数个数
@param argv 参数数组指针
@note
- 读入原图
- 转为灰度图
- 阀值控制
- 高斯均匀化
- 合并相加
@return int
*/
int main(int argc, char **argv)
{
//步骤1:读取原图
img = imread("chinesedragon.jpg"); //读取原图
namedWindow("Image-in", WINDOW_AUTOSIZE); //创建窗口
imshow("Image-in", img); // 显示原图
//步骤2:转为灰度图
Mat imggrey; //不用初始化
cvtColor(img, imggrey, COLOR_BGR2GRAY); //转为灰度图
imshow("Image-grey", imggrey); //显示灰度图
//步骤3:阀值处理
Mat tmp = img.clone(); //临时图像 克隆一份
//循环进行阀值处理,小于阀值的设定为黑色
for (int i = 0; i < tmp.rows; i++) //行循环
{
for (int j = 0; j < tmp.cols; j++) //列循环
{
//小于阀值的设定为黑色
if (imggrey.at<uchar>(i, j) < THRESHOLD_COLOR)
{
tmp.at<Vec3b>(i, j)[0] = 0; //blue
tmp.at<Vec3b>(i, j)[1] = 0; //green
tmp.at<Vec3b>(i, j)[2] = 0; //red
} //if
} //for j
} //for i
imshow("Image-threshold", tmp); //显示threshold
//Step 4:高斯均匀化
Mat blur; //均匀化
Size ks(7, 7); //size
GaussianBlur(tmp, blur, ks, 1); //高斯均匀化
imshow("Image-GaussianBlur", blur); //show blur
//Step 5: 图像相加
unsigned int r1; //临时变量
Vec3b *ptr_s; //原图的行指针
Vec3b *ptr_d; //目标图的行指针
//逐行扫描处理
for (int i = 0; i < tmp.rows; i++)
{
ptr_s = img.ptr<Vec3b>(i); //原图的行指针
ptr_d = blur.ptr<Vec3b>(i); //目标图的行指针
//逐列扫描处理
for (int j = 0; j < tmp.cols; j++)
{
for (int k = 0; k < 3; k++) //B,G,R循环进行叠加越界判断
{
r1 = A_VALUE * ptr_s[j][k] + B_VALUE * ptr_d[j][k]; //加权平均
if (r1 > 0xff)
r1 = 0xff; //最大255
ptr_d[j][k] = r1; //赋值
} //for k
} //for j
} //for i
imshow("Image-bloom", blur); //显示最终图像
//等待按键,ESC退出
cv::waitKey();
/*不用销毁窗口,可以自动销毁
destroyWindow("Image-in");
destroyWindow("Image-grey");
destroyWindow("Image-threshold");
destroyWindow("Image-gaussianblur");
destroyWindow("Image-bloom");
*/
return 0;
}
2.运行结果
原图:
灰度图阀值
高斯均匀化
炫光
总结
显示了图像的Bloom过程和结果图。
显示了OpenCV4相关的代码书写方式