学更好的别人,
做更好的自己。
——《微卡智享》
本文长度为1671字,预计阅读5分钟
前言
前两天刷B站时无意间刷到一个图片缩小后内容变的完全不同,蛮有趣的,视频下面也有源码地址,是用Python实现的,所以决定用C OpenCV也来玩玩这个。
1
思路来源
视频地址:https://www.bilibili.com/video/BV1Lf4y1r7dZ
源码地址:https://github.com/3150601355/SimpleScaleDown
实现效果
实现思路
# | 实现思路 |
---|---|
1 | 缩小后看到的图调整到正常图像缩小10倍后的大小 |
2 | 使用最邻近像素的原理将缩小后的图像像素点在正常图像上替换 |
3 | 替换完成的图像保存为新的文件 |
最近邻实现原理
01
放大效果
02
缩小效果
按照上面的原理,我们将隐藏的图缩小到原来图像十分之一后,针对关键的像素点替换掉我们缩小后的图像的像素点即可。
可以看到上图中我们把图像放大后,会有马赛克的小点,其实就是把我们缩小的图像像素点已经替换完成了。
代码实现
微卡智享
代码语言:javascript复制#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
Mat matresize(Mat& bigsrc, Mat& smallsrc, int step=10);
int main(int argc, char** argv) {
//读取图像一
Mat src1 = imread("E:/DCIM/Resize/src1.png");
imshow("src1", src1);
//读取图像二
Mat src2 = imread("E:/DCIM/Resize/src2.png");
imshow("src2", src2);
//根据两个图像生成新的Mat
Mat dst = matresize(src1, src2);
//将图像保存到本地
imwrite("E:/DCIM/Resize/resize.png", dst);
imshow("resize", dst);
waitKey(0);
return 0;
}
//第二张图为第一张图的10倍缩小
Mat matresize(Mat& bigsrc, Mat& smallsrc, int step)
{
//如果倍数小于等于0直接退出
if (step <= 0) return Mat();
Mat dst, tmpsrc;
//复制输出图像
bigsrc.copyTo(dst);
//计算第二张图要缩放的大小
int calccol = bigsrc.cols / step;
int calcrow = bigsrc.rows / step;
resize(smallsrc, tmpsrc, Size(calccol, calcrow));
for (int col = 0; col < calccol; col) {
for (int row = 0; row < calcrow; row) {
int mapcol = col * step step * 0.5;
int maprow = row * step step * 0.5;
//改变输出图的值
if (mapcol < dst.cols && maprow < dst.rows) {
dst.at<Vec3b>(maprow, mapcol) = tmpsrc.at<Vec3b>(row, col);
}
}
}
return dst;
}
运行效果
源码地址
https://github.com/Vaccae/OpenCVDemoCpp.git
点击下方的原文链接可以跳转到码云的源码地址。
完