Blur
Deprecated
GaussianBlur
// 高斯函数
double gaussian(double x, double sigma) {
return exp(-(x * x) / (2 * sigma * sigma));
}
// 高斯滤波函数
void gaussian_filter(std::shared_ptr<PrimitiveObject> &image, std::shared_ptr<PrimitiveObject> &imagetmp, int width, int height, int sigma) {
// 计算高斯核大小
int size = (int)(2 * sigma + 1);
if (size % 2 == 0) {
size++;
}
// 创建高斯核
float* kernel = new float[size];
float sum = 0.0;
int mid = size / 2;
for (int i = 0; i < size; i++) {
kernel[i] = gaussian(i - mid, sigma);
sum += kernel[i];
}
for (int i = 0; i < size; i++) {
kernel[i] /= sum;
}
// 对每个像素进行卷积操作
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
float sum0 = 0.0, sum1 = 0.0, sum2 = 0.0;
for (int i = -mid; i <= mid; i++) {
int nx = x + i;
if (nx < 0 || nx >= width) {
continue;
}
sum0 += kernel[i + mid] * image->verts[y * width + nx][0];
sum1 += kernel[i + mid] * image->verts[y * width + nx][1];
sum2 += kernel[i + mid] * image->verts[y * width + nx][2];
}
imagetmp->verts[y * width + x] = {sum0,sum1,sum2};
}
}
image = imagetmp;
// 释放内存
delete[] kernel;
}
#include <iostream>
#include <cmath>
using namespace std;
// 高斯函数
double gaussian(double x, double sigma) {
return exp(-(x * x) / (2 * sigma * sigma));
}
// 高斯滤波函数
void gaussian_filter(unsigned char* image, int width, int height, int channel, double sigma) {
// 定义一个和原图像相同大小的新图像
unsigned char* new_image = new unsigned char[width * height * channel];
memcpy(new_image, image, width * height * channel);
// 计算高斯核大小
int size = (int)(2 * sigma + 1);
if (size % 2 == 0) {
size++;
}
// 创建高斯核
double* kernel = new double[size];
double sum = 0.0;
int mid = size / 2;
for (int i = 0; i < size; i++) {
kernel[i] = gaussian(i - mid, sigma);
sum += kernel[i];
}
for (int i = 0; i < size; i++) {
kernel[i] /= sum;
}
// 对每个像素进行卷积操作
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
for (int c = 0; c < channel; c++) {
double sum = 0.0;
for (int i = -mid; i <= mid; i++) {
int nx = x + i;
if (nx < 0 || nx >= width) {
continue;
}
sum += kernel[i + mid] * image[(y * width + nx) * channel + c];
}
new_image[(y * width + x) * channel + c] = (unsigned char)sum;
}
}
}
// 将新图像复制回原图像
memcpy(image, new_image, width * height * channel);
// 释放内存
delete[] new_image;
delete[] kernel;
}
int main() {
// 读取图像
Mat img = imread("test.jpg", IMREAD_COLOR);
if (img.empty()) {
cerr << "Failed to read image" << endl;
return -1;
}
// 将图像转为灰度图像
Mat gray_img;
cvtColor(img, gray_img, COLOR_BGR2GRAY);
// 将图像数据复制到一个数组中
unsigned char* data = gray_img.data;
int width = gray_img.cols;
int height = gray_img.rows;
int channel = gray_img.channels();
// 进行高斯滤波
gaussian_filter(data, width, height, channel, 1.0);
// 将数组中的数据复制回图像
memcpy(gray_img.data, data, width * height * channel);
// 显示图像
imshow("Gaussian filter", gray_img);
waitKey(0);
return 0;
}
MedianBlur
// 定义一个结构体,用于存储像素点的信息
struct Pixel {
int x;
int y;
int value;
};
// MedianBlur函数,实现中值滤波操作
void MedianBlur(std::shared_ptr<PrimitiveObject> &image, std::shared_ptr<PrimitiveObject> &imagetmp, int width, int height, int kernel_size) {
// 定义一个vector,用于存储周围像素的值
using kernel = std::tuple<float, float, float>;
kernel n = {0, 0, 0};
std::vector<kernel> kernel_values(kernel_size * kernel_size);
// 遍历图像中的每个像素点
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
// 获取当前像素点的值
int current_value0 = image->verts[y * width + x][0];
int current_value1 = image->verts[y * width + x][1];
int current_value2 = image->verts[y * width + x][2];
// 遍历周围像素,获取像素值和坐标信息
for (int ky = 0; ky < kernel_size; ++ky) {
for (int kx = 0; kx < kernel_size; ++kx) {
int px = x - kernel_size / 2 + kx;
int py = y - kernel_size / 2 + ky;
// 判断像素是否越界,如果越界则使用当前像素值作为周围像素值
if (px < 0 || px >= width || py < 0 || py >= height) {
kernel_values[ky * kernel_size + kx] = {current_value0,current_value1,current_value2};
}
else {
kernel_values[ky * kernel_size + kx] = {image->verts[py * width + px][0],image->verts[py * width + px][1],image->verts[py * width + px][2]};
}
}
}
// 对周围像素的值进行排序,并取中间值作为新的像素值
std::sort(kernel_values.begin(), kernel_values.end());
float new_value0 = std::get<0>(kernel_values[kernel_size * kernel_size / 2]);
float new_value1 = std::get<1>(kernel_values[kernel_size * kernel_size / 2]);
float new_value2 = std::get<2>(kernel_values[kernel_size * kernel_size / 2]);
// 将新的像素值赋值给输出图像
imagetmp->verts[y * width + x] = {new_value0,new_value1,new_value2};
}
}
image = imagetmp;
}
#include <iostream>
#include <vector>
#include <algorithm>
// 定义一个结构体,用于存储像素点的信息
struct Pixel {
int x;
int y;
int value;
};
// MedianBlur函数,实现中值滤波操作
void MedianBlur(const unsigned char* input_image, unsigned char* output_image, int width, int height, int kernel_size) {
// 定义一个vector,用于存储周围像素的值
std::vector<int> kernel_values(kernel_size * kernel_size);
// 遍历图像中的每个像素点
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
// 获取当前像素点的值
int current_value = input_image[y * width + x];
// 定义一个vector,用于存储周围像素的信息
std::vector<Pixel> kernel_pixels(kernel_size * kernel_size);
// 遍历周围像素,获取像素值和坐标信息
for (int ky = 0; ky < kernel_size; ++ky) {
for (int kx = 0; kx < kernel_size; ++kx) {
int px = x - kernel_size / 2 + kx;
int py = y - kernel_size / 2 + ky;
// 判断像素是否越界,如果越界则使用当前像素值作为周围像素值
if (px < 0 || px >= width || py < 0 || py >= height) {
kernel_values[ky * kernel_size + kx] = current_value;
}
else {
kernel_values[ky * kernel_size + kx] = input_image[py * width + px];
}
// 将像素信息存储到vector中
kernel_pixels[ky * kernel_size + kx] = { px, py, kernel_values[ky * kernel_size + kx] };
}
}
// 对周围像素的值进行排序,并取中间值作为新的像素值
std::sort(kernel_values.begin(), kernel_values.end());
int new_value = kernel_values[kernel_size * kernel_size / 2];
// 将新的像素值赋值给输出图像
output_image[y * width + x] = new_value;
}
}
}
int main() {
// 定义图像的宽度和高度
int width = 640;
int height = 480;
// 定义一个用于存储图像数据的数组
unsigned char* input_image = new unsigned char[width
BilateralBlur
// 定义一个函数,用于计算双边权重
float bilateral(float src, float dst, float sigma_s, float sigma_r) {
return gaussian(src - dst, sigma_s) * gaussian(abs(src - dst), sigma_r);
}
// 定义一个函数,用于对图像进行双边滤波
void bilateralFilter(std::shared_ptr<PrimitiveObject> &image, std::shared_ptr<PrimitiveObject> &imagetmp, int width, int height, float sigma_s, float sigma_r) {
// 计算卷积核的半径
int k = ceil(3 * sigma_s);
// 定义一个临时数组,用于存储每个像素点的中间值
float* tmp = new float[width * height];
for (int i = k; i < height-k; i++) {
for (int j = k; j < width-k; j++) {
// 定义变量,用于存储像素值的加权平均值
float sum0 = 0, sum1 = 0, sum2 = 0;
// 定义变量,用于存储权重的和
float wsum0 = 0,wsum1 = 0,wsum2 = 0;
for (int m = -k; m <= k; m++) {
for (int n = -k; n <= k; n++) {
// 计算双边权重
float w0 = bilateral(image->verts[i*width+j][0],image->verts[(i+m)*width+j+n][0], sigma_s, sigma_r);
float w1 = bilateral(image->verts[i*width+j][1],image->verts[(i+m)*width+j+n][1], sigma_s, sigma_r);
float w2 = bilateral(image->verts[i*width+j][2],image->verts[(i+m)*width+j+n][2], sigma_s, sigma_r);
// 计算加权平均值
sum0 += w0 * image->verts[(i+m)*width+j+n][0];
sum1 += w1 * image->verts[(i+m)*width+j+n][1];
sum2 += w2 * image->verts[(i+m)*width+j+n][2];
// 计算权重的和
wsum0 += w0;
wsum1 += w1;
wsum2 += w2;
}
}
imagetmp->verts[i*width+j] = {sum0 / wsum0,sum1/ wsum1, sum2 / wsum2}; // 计算每个像素点的中间值,并将结果存储到临时数组中
}
}
image = imagetmp;
}
#include <iostream>
#include <cmath>
using namespace std;
// 定义一个函数,用于计算高斯权重
float gaussian(float x, float sigma) {
return exp(-(x*x) / (2*sigma*sigma));
}
// 定义一个函数,用于计算双边权重
float bilateral(float src, float dst, float sigma_s, float sigma_r) {
return gaussian(src - dst, sigma_s) * gaussian(abs(src - dst), sigma_r);
}
// 定义一个函数,用于对图像进行双边滤波
void bilateralFilter(float* src, float* dst, int width, int height, float sigma_s, float sigma_r) {
int k = ceil(3 * sigma_s); // 计算卷积核的半径
float* tmp = new float[width * height]; // 定义一个临时数组,用于存储每个像素点的中间值
for (int i = k; i < height-k; i++) {
for (int j = k; j < width-k; j++) {
float sum = 0; // 定义一个变量,用于存储像素值的加权平均值
float wsum = 0; // 定义一个变量,用于存储权重的和
for (int m = -k; m <= k; m++) {
for (int n = -k; n <= k; n++) {
float w = bilateral(src[i*width+j], src[(i+m)*width+j+n], sigma_s, sigma_r); // 计算双边权重
sum += w * src[(i+m)*width+j+n]; // 计算加权平均值
wsum += w; // 计算权重的和
}
}
tmp[i*width+j] = sum / wsum; // 计算每个像素点的中间值,并将结果存储到临时数组中
}
}
memcpy(dst, tmp, sizeof(float) * width * height); // 将临时数组中的数据拷贝到输出数组中
delete[] tmp; // 释放临时数组
}
int main() {
float src[] = {1, 5, 3, 6, 9, 2, 8, 7, 4}; // 输入数组
float dst[9]; // 输出数组
float sigma_s = 1.0f; // 空间域标准差
float sigma_r = 1.0f; // 灰度值域标准差
bilateralFilter(src, dst, 3, 3, sigma_s, sigma_r); // 对输入数组进行双边滤波
#include <iostream>
#include <cmath>
using namespace std;
// 定义一个函数,用于计算两个像素之间的距离
float distance(int x1, int y1, int x2, int y2) {
return sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2));
}
// 定义一个函数,用于计算双边滤波中的权重
float weight(float distance, float sigma_d, float sigma_r) {
return exp(-pow(distance, 2) / (2 * pow(sigma_d, 2))) * exp(-pow(distance, 2) / (2 * pow(sigma_r, 2)));
}
// 定义一个函数,用于对图像进行双边滤波
void bilateralFilter(int* src, int* dst, int width, int height, float sigma_d, float sigma_r) {
int k = 2 * ceil(sigma_d) + 1; // 计算卷积核的大小
float w_sum = 0; // 定义一个变量,用于存储权重的和
for (int i = k/2; i < height-k/2; i++) {
for (int j = k/2; j < width-k/2; j++) {
float sum = 0; // 定义一个变量,用于存储加权平均值
w_sum = 0; // 重置权重的和
for (int m = -k/2; m <= k/2; m++) {
for (int n = -k/2; n <= k/2; n++) {
int x = i + m;
int y = j + n;
if (x >= 0 && x < height && y >= 0 && y < width) { // 如果像素在图像范围内
float d = distance(i, j, x, y); // 计算像素之间的距离
float w = weight(d, sigma_d, sigma_r); // 计算像素之间的权重
sum += w * src[x*width+y]; // 将加权像素值相加
w_sum += w; // 将权重相加
}
}
}
dst[i*width+j] = round(sum / w_sum); // 计算加权平均值,并将结果存储到输出图像中
}
}
}
int main() {
int src[] = {1, 5, 3, 6, 9, 2, 8, 7, 4}; // 输入数组
int dst[9]; // 输出数组
float sigma_d = 1; // 空间域标准差
float sigma_r = 1
文章评论