#include<iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
void color_reduce(Mat& image, int x);
void colorReduce3(Mat& image, int div);//将一张图片的像素改为64x64
void colorReduce4(Mat& image, int div);
void colorReduce5(Mat& image, int div);
int main()
{
Mat image = imread("大教堂.jpg");
resize(image,image,Size(),0.4,0.4);
colorReduce5(image,64);
imshow("结果",image);
waitKey(0);
return 0;
}
//方法1
void colorReduce1(Mat& image, int div = 64)//将一张图片的像素改为64x64
{
//大体思路:将图片中的每个像素的值改为其像素空间中,256/64大小方格中的中间的值。
int n1 = image.rows;//图片的行数。
int nc = image.cols * image.channels(); //列数乘以图片的通道值。//因为rgb是逐行连续存储的。r g b
for (int j = 0; j < n1; j++)
{
uchar* data = image.ptr<uchar>(j);//取图片第j行的首个像素点
for (int i = 0; i < nc; i++)
{
data[i] = data[i] / div * div + div / 2;//将此像素值改为其方格中间的像素值。
}
}
}
//方法2 指针法
void colorReduce2(Mat& image, int div = 64)
{
int nl = image.rows;
int nc = image.cols*image.channels();
for (int i = 0; i < nl; ++i)
{
uchar* p = image.ptr<uchar>(i);
for (int j = 0; j < nc; ++j)
{
p[j] = p[j] / div * div + div / 2;
}
}
}
//方法3 位运算法。
void colorReduce3(Mat& image, int div = 64)
{
//由256到64就是位左移动6位。
int nl = image.rows;
int nc = image.cols * image.channels();
int n = 0xff << static_cast<int>(log(static_cast<double>(div)) / log(2.0));//0xff代表了256
for (int i = 0; i < nl; ++i)
{
uchar* p = image.ptr<uchar>(i);
for (int j = 0; j < nc; j++)
{
p[j] = p[j] & n + div / 2;
}
}
}
//方法3 at()函数法
void colorReduce4(Mat& image, int div = 64)
{
int nl = image.rows;
int nc = image.cols;
for(int i=0;i<nl;i++)
for (int j = 0; j < nc; j++)
{
image.at<uchar>(i, j) = image.at<uchar>(i, j) / div * div + div / 2;
}
}
//方法4 向量vector法。
void colorReduce5(Mat& image, int div = 64)
{
Mat_<Vec3b>::iterator it = image.begin<Vec3b>();
for (; it != image.end<Vec3b>(); ++it)
{
(*it)[0] = saturate_cast<uchar>(((*it)[0]) / div * div + div / 2);
(*it)[1] = saturate_cast<uchar>(((*it)[1]) / div * div + div / 2);
(*it)[2] = saturate_cast<uchar>(((*it)[2]) / div * div + div / 2);
}
}
降低图像分辨率的几种方法
最新推荐文章于 2024-07-26 15:42:10 发布