#include <opencv2/opencv.hpp>
#include<opencv2\core\mat.inl.hpp>
#include<opencv2\core\mat.hpp>
#include<iostream>
using namespace std;
using namespace cv;
// 删除指定的一行
void DeleteOneColOfMat(Mat& object, int num)
{
if (num<0 || num >= object.cols)
{
cout << " 列标号不在矩阵正常范围内 " << endl;
}
else
{
if (num == object.cols - 1)
{
object = object.t();
object.pop_back();
object = object.t();
}
else
{
for (int i = num + 1;i < object.cols;i++)
{
object.col(i - 1) = object.col(i) + Scalar(0, 0, 0, 0);
}
object = object.t();
object.pop_back();
object = object.t();
}
}
}
// 删除指定的一列
void DeleteOneRowOfMat(Mat& object, int num)
{
if (num<0 || num >= object.rows)
{
cout << " 行标号不在矩阵正常范围内 " << endl;
}
else
{
if (num == object.rows - 1)
{
object.pop_back();
}
else
{
for (int i = num + 1;i < object.rows;i++)
{
object.row(i - 1) = object.row(i) + Scalar(0, 0, 0, 0);
}
object.pop_back();
}
}
}
// 生成高斯滤波器
int **Gussion_template(int ksize, double sigma) {
static double pi = 3.1415926;
double ratio = 1 / (2 * pi * sigma * sigma);
int center = ksize / 2;
double** Matrix = new double*[ksize];
for (int i = 0; i < ksize; i++) {
Matrix[i] = new double[ksize];
}
double x, y;
for (int i = 0; i < ksize; i++) {
x = pow(i - center, 2);
for (int j = 0; j < ksize; j++) {
y = pow(j - center, 2);
Matrix[i][j] = (ratio * exp(-(x + y) / (2 * sigma * sigma)));
}
}
double k = 1 / Matrix[0][0];
for (int i = 0; i < ksize;i++) {
for (int j = 0; j < ksize; j++) {
Matrix[i][j] *= k;
}
}
int **Matrix_int = new int*[ksize];
for (int i = 0; i < ksize; i++) {
Matrix_int[i] = new int[ksize];
for (int j = 0; j < ksize; j++) {
Matrix_int[i][j] = (int)Matrix[i][j];
}
}
return Matrix_int;
}
// 应用高斯滤波器到指定的图片上
void Gaussion_filter(Mat &src_img, Mat &dst_img, int ksize, double sigma) {
CV_Assert(src_img.channels() || src_img.channels() == 3);
int **g_template = Gussion_template(ksize, sigma);
double radio = 0;
for (int i = 0; i < ksize; i++) {
for (int j = 0; j < ksize;j++) {
radio += g_template[i][j];
}
}
for (int i = 0; i < ksize; i++) {
for (int j = 0; j < ksize; j++)
cout << g_template[i][j] << " ";
cout << endl;
}
int center = ksize / 2;
int border = center;
cout << src_img.cols << " " << src_img.rows << endl;
copyMakeBorder(src_img, src_img, border, border, border, border, BorderTypes::BORDER_CONSTANT);
cout << src_img.cols << " " << src_img.rows << endl;
int row = src_img.rows;
int col = src_img.cols;
for (int i = 0; i < row - ksize; i++) {
for (int j = 0; j < col - ksize; j++) {
if(src_img.channels() == 1){
dst_img.at<float>(i, j) = 0;
for (int k = 0; k < ksize; k++) {
for (int l = 0; l < ksize; l++) {
dst_img.at<float>(i, j) += src_img.at<float>(i + k, j + l) * g_template[k][l];
}
}
dst_img.at<float>(i, j) /= radio;
if (dst_img.at<float >(i, j) / radio > 255) {
dst_img.at<float>(i, j) = 255;
}
}
else if (src_img.channels() == 3) {
double r = 0;
double g = 0;
double b = 0;
for (int k = 0; k < ksize; k++) {
for (int l = 0; l < ksize; l++) {
Vec3b rgb = src_img.at<Vec3b>(i + k, j + l);
int s = g_template[k][l];
r += rgb[0] * s;
g += rgb[1] * s;
b += rgb[2] * s;
}
}
r /= radio;
g /= radio;
b /= radio;
if (r / radio > 255) r = 255;
if (g / radio > 255) g = 255;
if (b / radio > 255) b = 255;
Vec3b rgb_dst = {static_cast<uchar>(r), static_cast<uchar>(g ),static_cast<uchar>(b ) };
dst_img.at<Vec3b>(i, j) = rgb_dst;
}
}
}
cout << dst_img.cols << " " << dst_img.rows << endl;
}
//去除边
void remove_border(Mat &image_src, int ksize) {
for (int i = 0; i < ksize / 2; i++) {
DeleteOneColOfMat(image_src, image_src.cols - 1);
DeleteOneColOfMat(image_src, 0);
DeleteOneRowOfMat(image_src, image_src.rows - 1);
DeleteOneRowOfMat(image_src, 0);
}
cout << image_src.cols << " " << image_src.rows << endl;
}
int main() {
Mat image_src = imread("111.jpg");
Mat image = imread("111.jpg");
Mat image2 = imread("222.jpg");
Mat image2_src = imread("222.jpg");
int ksize = 25;
double sigma = 8;
Mat result_test;
GaussianBlur(image, result_test, Size(15, 15), 5);
namedWindow("sys_gaussion", WINDOW_NORMAL);
imshow("sys_gaussion", result_test);
waitKey();
Gaussion_filter(image_src, image, ksize, sigma);
namedWindow("MyGaussion", WINDOW_NORMAL);
imshow("MyGaussion", image);
waitKey();
Gaussion_filter(image2_src, image2, ksize, sigma);
remove_border(image2_src, ksize);
int count = 0;
for (int i = 0; i < image2_src.rows; i++) {
for (int j = 0; j < image2_src.cols;j++) {
int r = 0;
int g = 0;
int b = 0;
Vec3b rgb = image2_src.at<Vec3b>(i, j);
Vec3b rgb1 = image2.at<Vec3b>(i, j);
r += rgb[0] + 16 - rgb1[0];
g += rgb[1] + 16- rgb1[1];
b += rgb[2] + 16 - rgb1[2];
if (r > 255) r = 255;
if (g > 255) g = 255;
if (b > 255) b = 255;
if (r < 0) r = 0;
if (g < 0) g = 0;
if (b < 0) b = 0;
Vec3b rgb_dst = { static_cast<uchar>(r), static_cast<uchar>(g),static_cast<uchar>(b) };
image2.at<Vec3b>(i, j) = rgb_dst;
}
}
namedWindow("Mycat", WINDOW_NORMAL);
imshow("Mycat", image2);
waitKey();
Mat result;
result = image + image2;
namedWindow("hybrid", WINDOW_NORMAL);
imshow("hybrid", result);
waitKey();
system("pause");
}