可以通过整图像的饱和度和亮度实现图像的月光度效果。
HSV空间是很容易实现对图像的饱和度和亮度进行调节的。
关于HSV空间的详细介绍见博文 https://www.hhai.cc/thread-212-1-1.html
所以思路就出来了,把图片先从BGR空间转换到HSV空间,在HSV空间调整完之后再转回BGR空间。
我们要实现下面三种月光度效果。
Python代码如下:
代码中用到的图片下载链接如下:
https://pan.baidu.com/s/1FPaoTbFRKITnVtvFIoL1Yw?pwd=eq8i
[Python] 纯文本查看 复制代码 # -*- coding: utf-8 -*-
# 出处:昊虹AI笔记网(hhai.cc)
# 用心记录计算机视觉和AI技术
# 博主微信/QQ 2487872782
# QQ群 271891601
# 欢迎技术交流与咨询
# OpenCV的版本为4.4.0
import numpy as np
import cv2 as cv
import sys
image = cv.imread('F:/material/images/2022/2022-06/01_woman.jpg')
if image is None:
print('Error: Could not load image')
sys.exit()
# cv.imshow('Source Image', image)
# 由于图片太大,不利于结果的观察,所以缩小一下,正式发布的的时候取消resize就行了。
image = cv.resize(image, (300, 300))
cv.imshow('Source Image', image)
image_hsv = cv.cvtColor(image, cv.COLOR_BGR2HSV)
# HSV三个通道分离
image_h = image_hsv[:, :, 0]
image_s = image_hsv[:, :, 1]
image_v = image_hsv[:, :, 2]
# scale1用于调整S通道的值
# scale2用于调整V通道的值
# 当scale1 = 0.4 scale2 = 0.6 时,对应的月光度为%30
# 当scale1 = 0.15 scale2 = 1.3 时,对应的月光度为%50
# 当scale1 = 0.08 scale2 = 1.95 时,对应的月光度为%100
scale1 = 0.4
scale2 = 0.6
image_s_scale = np.multiply(image_s, scale1) # 矩阵点乘
image_v_scale = np.multiply(image_v, scale2) # 矩阵点乘
image_s_scale = np.around(image_s_scale) # 点乘结果四舍五入取整
image_v_scale = np.around(image_v_scale) # 点乘结果四舍五入取整
image_v_scale = np.where(image_v_scale > 255, 255, image_v_scale) # 把超过255的值置为255
image_s_scale = image_s_scale.astype('uint8')
image_v_scale = image_v_scale.astype('uint8')
image_hsv_2 = cv.merge([image_h, image_s_scale, image_v_scale]) # HSV三个通道合并
dst_image = cv.cvtColor(image_hsv_2, cv.COLOR_HSV2BGR)
cv.imshow('Moonlight_Effect', dst_image)
cv.waitKey(0)
cv.destroyAllWindows()
C++代码如下:
[C++] 纯文本查看 复制代码 //出处:昊虹AI笔记网(hhai.cc)
//用心记录计算机视觉和AI技术
//博主微信/QQ 2487872782
//QQ群 271891601
//欢迎技术交流与咨询
//OpenCV版本 OpenCV3.0
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
//moonglight()为月光度效果添加函数,只支持30%、50%和100%这三种月光度效果
//第一个参数src为输入图像
//第一个参数dst为输入图像
//第三个参数moon_degree为月光程度,只能填30、50、100这三个值。
int moonglight(cv::Mat &src, cv::Mat &dst,int moon_degree)
{
Mat image_hsv;
cvtColor(src, image_hsv, cv::COLOR_BGR2HSV);
std::vector<cv::Mat> hsv_split_vec;
split(image_hsv, hsv_split_vec);
double scale1 = 0;
double scale2 = 0;
if (moon_degree == 30) //对应月光度为30%时的比例因子
{
scale1 = 0.4;
scale2 = 0.6;
}
else if (moon_degree == 50) //对应月光度为50%时的比例因子
{
scale1 = 0.15;
scale2 = 1.3;
}
else if (moon_degree == 100) //对应月光度为100%时的比例因子
{
scale1 = 0.08;
scale2 = 1.95;
}
else
{
printf("错误:不能处理的月光度程度\n");
return 0;
}
Mat ones1(hsv_split_vec[1].size(), hsv_split_vec[1].type(), cv::Scalar(1));
multiply(hsv_split_vec[1], ones1, hsv_split_vec[1], scale1, CV_8U);
multiply(hsv_split_vec[2], ones1, hsv_split_vec[2], scale2, CV_8U);
Mat dst_hsv;
merge(hsv_split_vec, dst_hsv);
cvtColor(dst_hsv, dst, cv::COLOR_HSV2BGR);
}
int main()
{
Mat src_image = imread("./01_woman_300.jpg");
if (src_image.empty())
{
std::cout << "Error: Could not load image" << std::endl;
return 0;
}
imshow("源图像", src_image);
//月光度为30%时的情况
Mat img_moonglight_30;
moonglight(src_image, img_moonglight_30, 30);
imshow("月光度30%", img_moonglight_30); //显示处理后的图像
imwrite("月光度30%.jpg", img_moonglight_30); //保存处理后的图像
//月光度为50%时的情况
Mat img_moonglight_50;
moonglight(src_image, img_moonglight_50, 50);
imshow("月光度50%", img_moonglight_50);
imwrite("月光度50%.jpg", img_moonglight_50);
//月光度为100%时的情况
Mat img_moonglight_100;
moonglight(src_image, img_moonglight_100, 100);
imshow("月光度100%", img_moonglight_100);
imwrite("月光度100%.jpg", img_moonglight_100);
waitKey();
return(0);
}
Python运行结果如下图所示:
月光度为30%的运行结果:
月光度为50%的运行结果:
月光度为100%的运行结果:
C++代码运行结果:略。
|