1.视频教程:
B站、网易云课堂、腾讯课堂
2.代码地址:
Gitee
Github
3.存储地址:
Google云
百度云:
提取码:
卷积的概念最早出现在,数字信号处理,而不是图像处理。
#include
#include
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat src = imread("E:/cats.jpg", IMREAD_COLOR);
if (src.empty()) {
printf("image is empty!!!");
return -1;
}
imshow("src", src);
int h = src.rows;
int w = src.cols;
Mat result = src.clone();
for (int row = 1; row < h - 1; row++) {
for (int col = 1; col < w - 1; col++) {
// 3*3卷积核
int sb = src.at<Vec3b>(row, col)[0] + src.at<Vec3b>(row - 1, col - 1)[0] + src.at<Vec3b>(row - 1, col)[0] +
src.at<Vec3b>(row-1, col+1)[0] + src.at<Vec3b>(row, col - 1)[0] + src.at<Vec3b>(row, col+1)[0] +
src.at<Vec3b>(row+1, col-1)[0] + src.at<Vec3b>(row+1, col)[0] + src.at<Vec3b>(row + 1, col+1)[0];
int sg = src.at<Vec3b>(row, col)[1] + src.at<Vec3b>(row - 1, col - 1)[1] + src.at<Vec3b>(row - 1, col)[1] +
src.at<Vec3b>(row - 1, col + 1)[1] + src.at<Vec3b>(row, col - 1)[1] + src.at<Vec3b>(row, col + 1)[1] +
src.at<Vec3b>(row + 1, col - 1)[1] + src.at<Vec3b>(row + 1, col)[1] + src.at<Vec3b>(row + 1, col + 1)[1];
int sr = src.at<Vec3b>(row, col)[2] + src.at<Vec3b>(row - 1, col - 1)[2] + src.at<Vec3b>(row - 1, col)[2] +
src.at<Vec3b>(row - 1, col + 1)[2] + src.at<Vec3b>(row, col - 1)[2] + src.at<Vec3b>(row, col + 1)[2] +
src.at<Vec3b>(row + 1, col - 1)[2] + src.at<Vec3b>(row + 1, col)[2] + src.at<Vec3b>(row + 1, col + 1)[2];
result.at<Vec3b>(row, col)[0] = sb / 9;
result.at<Vec3b>(row, col)[1] = sg / 9;
result.at<Vec3b>(row, col)[2] = sr / 9;
}
}
imshow("result", result);
waitKey(0);
destroyAllWindows();
return 0;
}
#include
#include
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat src = imread("E:/cats.jpg", IMREAD_COLOR);
if (src.empty()) {
printf("image is empty!!!");
return -1;
}
imshow("src", src);
Mat dst;
blur(src, dst, Size(3, 3), Point(-1, -1), BORDER_DEFAULT);
imshow("dst", dst);
waitKey(0);
destroyAllWindows();
return 0;
}
#include
#include
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat src = imread("E:/cats.jpg", IMREAD_COLOR);
if (src.empty()) {
printf("image is empty!!!");
return -1;
}
imshow("src", src);
Mat dst;
blur(src, dst, Size(12, 12), Point(-1, -1), BORDER_DEFAULT);
imshow("dst", dst);
waitKey(0);
destroyAllWindows();
return 0;
}
1.constant填充
2.replicate
3.wrap
4.reflect
5.default
#include
#include
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat src = imread("E:/cats.jpg", IMREAD_COLOR);
if (src.empty()) {
printf("image is empty!!!");
return -1;
}
imshow("src", src);
// 边缘填充
int border = 8;
Mat border_m;
copyMakeBorder(src, border_m, border, border, border, border, BORDER_DEFAULT);
imshow("border fill", border_m);
waitKey(0);
destroyAllWindows();
return 0;
}
#include
#include
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat src = imread("E:/cats.jpg", IMREAD_COLOR);
if (src.empty()) {
printf("image is empty!!!");
return -1;
}
imshow("src", src);
// 边缘填充
int border = 8;
Mat border_m;
copyMakeBorder(src, border_m, border, border, border, border, BORDER_CONSTANT);
imshow("border fill", border_m);
waitKey(0);
destroyAllWindows();
return 0;
}
#include
#include
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat src = imread("E:/cats.jpg", IMREAD_COLOR);
if (src.empty()) {
printf("image is empty!!!");
return -1;
}
imshow("src", src);
// 边缘填充
int border = 8;
Mat border_m;
copyMakeBorder(src, border_m, border, border, border, border, BORDER_CONSTANT,Scalar(255,0,0));
imshow("border fill", border_m);
waitKey(0);
destroyAllWindows();
return 0;
}
#include
#include
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat src = imread("E:/cats.jpg", IMREAD_COLOR);
if (src.empty()) {
printf("image is empty!!!");
return -1;
}
imshow("src", src);
Mat dst;
GaussianBlur(src, dst, Size(5, 5), 0);
imshow("gaussina blur", dst);
waitKey(0);
destroyAllWindows();
return 0;
}
#include
#include
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat src = imread("E:/cats.jpg", IMREAD_COLOR);
if (src.empty()) {
printf("image is empty!!!");
return -1;
}
imshow("src", src);
Mat dst;
// 盒子模糊,即均值模糊
boxFilter(src, dst,-1, Size(5, 5),Point(-1,-1),true,BORDER_DEFAULT);
imshow("boxFilter blur", dst);
waitKey(0);
destroyAllWindows();
return 0;
}
#include
#include
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat src = imread("E:/cats.jpg", IMREAD_COLOR);
if (src.empty()) {
printf("image is empty!!!");
return -1;
}
imshow("src", src);
Mat dst;
// 盒子模糊,即均值模糊
boxFilter(src, dst,-1, Size(1, 25),Point(-1,-1),true,BORDER_DEFAULT);
imshow("boxFilter blur", dst);
waitKey(0);
destroyAllWindows();
return 0;
}
针对不同卷积核系数,图像输出类型数值范围
CV_32F/CV_32S
类型转换与显示支持
#include
#include
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat src = imread("E:/cats.jpg", IMREAD_COLOR);
if (src.empty()) {
printf("image is empty!!!");
return -1;
}
imshow("src", src);
// 自定义滤波 - 均值卷积
int k = 15;
Mat mkernel = Mat::ones(k, k, CV_32F) / (float)(k*k);
Mat dst;
filter2D(src, dst, -1, mkernel, Point(-1, -1), 0, BORDER_DEFAULT);
imshow("custom mean filter", dst);
// 非均值滤波
Mat robot = (Mat_ <int>(2, 2) << 1, 0, 0, -1);
Mat result;
filter2D(src, result, CV_32F, robot, Point(-1, -1), 127, BORDER_DEFAULT);
convertScaleAbs(result, result);
imshow("robot filter", result);
waitKey(0);
destroyAllWindows();
return 0;
}