java用opencv实现滤镜,OpenCV

这是一个比较有意思的demo,用到了播送融合,具体效果见下图:

d2050d1dca1c805301faa80e05097c42.png

文件结构如图所示

1cee6a463b237eb79d9df4ab854eef52.png

主程序代码

#include"stdafx.h"

#include

#include"HSL.hpp"

using namespace std;

using namespace cv;

const string window_name = "photo";

static Mat src;

static HSL hsl;

static int color = 0;

static int hue = 180;

static int saturation = 100;

static int brightness = 100;

#define VP vector

//寻找最大的轮廓

VP FindBigestContour(Mat src) {

int imax = 0; //代表最大轮廓的序号

int imaxcontour = -1; //代表最大轮廓的大小

std::vector<:vector>>contours;

findContours(src, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);

for (int i = 0; i < contours.size(); i++) {

int itmp = contourArea(contours[i]);//这里采用的是轮廓大小

if (imaxcontour < itmp) {

imax = i;

imaxcontour = itmp;

}

}

return contours[imax];

}

//提高饱和度

Mat EnhanceSaturation(Mat temp)

{

Mat matDst;

Mat Img_out(temp.size(), CV_32FC3);

temp.convertTo(Img_out, CV_32FC3);

Mat Img_in(temp.size(), CV_32FC3);

temp.convertTo(Img_in, CV_32FC3);

// define the iterator of the input image

MatIterator_ inp_begin, inp_end;

inp_begin = Img_in.begin();

inp_end = Img_in.end();

// define the iterator of the output image

MatIterator_ out_begin, out_end;

out_begin = Img_out.begin();

out_end = Img_out.end();

// increment (-100.0, 100.0)

float Increment = 50.0 / 100.0; //饱和度参数调整

float delta = 0;

float minVal, maxVal;

float t1, t2, t3;

float L, S;

float alpha;

for (; inp_begin != inp_end; inp_begin++, out_begin++)

{

t1 = (*inp_begin)[0];

t2 = (*inp_begin)[1];

t3 = (*inp_begin)[2];

minVal = std::min(std::min(t1, t2), t3);

maxVal = std::max(std::max(t1, t2), t3);

delta = (maxVal - minVal) / 255.0;

L = 0.5*(maxVal + minVal) / 255.0;

S = std::max(0.5*delta / L, 0.5*delta / (1 - L));

if (Increment > 0)

{

alpha = max(S, 1 - Increment);

alpha = 1.0 / alpha - 1;

(*out_begin)[0] = (*inp_begin)[0] + ((*inp_begin)[0] - L * 255.0)*alpha;

(*out_begin)[1] = (*inp_begin)[1] + ((*inp_begin)[1] - L * 255.0)*alpha;

(*out_begin)[2] = (*inp_begin)[2] + ((*inp_begin)[2] - L * 255.0)*alpha;

}

else

{

alpha = Increment;

(*out_begin)[0] = L * 255.0 + ((*inp_begin)[0] - L * 255.0)*(1 + alpha);

(*out_begin)[1] = L * 255.0 + ((*inp_begin)[1] - L * 255.0)*(1 + alpha);

(*out_begin)[2] = L * 255.0 + ((*inp_begin)[2] - L * 255.0)*(1 + alpha);

}

}

Img_out /= 255;

Img_out.convertTo(matDst, CV_8UC3, 255);

return matDst;

}

int _tmain(int argc, _TCHAR* argv[])

{

Mat matSrc = imread("../src3.jpg");

Mat matCloud = imread("../cloud2.jpg");

Mat temp; Mat matDst; Mat mask;

vector planes;

/************************************************************************/

/* 1.背景(天空)分割 */

/************************************************************************/

cvtColor(matSrc, temp, COLOR_BGR2HSV);

split(temp, planes);

equalizeHist(planes[2], planes[2]);//对v通道进行equalizeHist

merge(planes, temp);

inRange(temp, Scalar(100, 43, 46), Scalar(124, 255, 255), temp);

erode(temp, temp, Mat());//形态学变换,填补内部空洞

dilate(temp, temp, Mat());

mask = temp.clone();//将结果存入mask

/************************************************************************/

/* 2.再融合,以1的结果mask,直接将云图拷贝过来(之前需要先做尺度变换) */

/************************************************************************/

//寻找白色区域最大外接矩形的代码

VP maxCountour = FindBigestContour(mask);

Rect maxRect = boundingRect(maxCountour);

if (maxRect.height == 0 || maxRect.width == 0)

maxRect = Rect(0, 0, mask.cols, mask.rows);//特殊情况

matDst = matSrc.clone();

//注意这里的mask 需要和matCloud同样尺寸

mask = mask(maxRect);

resize(matCloud, matCloud, maxRect.size());

//seamless clone

//中间位置为蓝天的背景位置

Point center = Point((maxRect.x + maxRect.width) / 2, (maxRect.y + maxRect.height) / 2);

Mat normal_clone;

Mat mixed_clone;

Mat monochrome_clone;

seamlessClone(matCloud, matSrc, mask, center, normal_clone, NORMAL_CLONE);

seamlessClone(matCloud, matSrc, mask, center, mixed_clone, MIXED_CLONE);

seamlessClone(matCloud, matSrc, mask, center, monochrome_clone, MONOCHROME_TRANSFER);

/************************************************************************/

/* 3.卡通画处理 */

/************************************************************************/

//双边滤波

bilateralFilter(normal_clone, temp, 5, 10.0, 2.0);

//彩色直方图均衡,将RGB图像转到YCbCr分量,然后对Y分量上的图像进行直方图均衡化

cvtColor(temp, temp, COLOR_BGR2YCrCb);

split(temp, planes);

equalizeHist(planes[0], planes[0]);

merge(planes, temp);

cvtColor(temp, temp, COLOR_YCrCb2BGR);

//提高图像饱和度

matDst = EnhanceSaturation(temp);

imshow("原始图", matSrc);

imshow("结果图", matDst);

cv::waitKey();

getchar();

return 0;

}

标签:begin,Mat,temp,mask,inp,名字,OpenCV,滤镜,out

来源: https://www.cnblogs.com/liuboblog/p/12026925.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值