1.自选一幅自然景观图像(照片),用指针扫描方式实现图像减色功能,显示原图和减色后的结果图。减色算法可采用任何一种,例如整数除法、取模运算符、位运算等,(最好是每一种都实现一下,封装到不同的函数里,因为后面课程中会对每一种实现进行测速)
源码:
#include<opencv2\highgui.hpp>
#include<iostream>
using namespace std;
using namespace cv;
void colorReduce(cv::Mat image);
void getMo(Mat image);
void weiMeth(Mat image,int n=6){
uchar div=pow(2,n);
uchar div2=div>>1;
uchar mask = uchar(0xFF) << n;
int nr=image.rows;
int nc = image.cols * image.channels();
for (int j = 0; j < nr; j++) { // 遍历每一行
// 取得行j的地址
uchar* data = image.ptr<uchar>(j);
// 遍历当前行每一个元素
for (int i = 0; i < nc; i++) {
// 处理每个元素---------------------
*data &= mask; // 掩码,将后n位设为0
*data++ += div2;
}
}
}
int main()
{
Mat image=imread("原图.png");
imshow("原图",image);
if(image.empty())
{
cout<<"empty image";
getchar();
return 0;
}
colorReduce(image);
imshow("减色图",image);
getMo(image);
imshow("取模运算符",image);
weiMeth(image);
imshow("位运算符",image);
waitKey();
return 0;
}
void colorReduce(cv::Mat image) {
int div = 64;
int nr = image.rows; // 行数
// 每行的元素数量(注意不是像素数量)
int nc = image.cols * image.channels();
for (int j = 0; j < nr; j++) { // 遍历每一行
// 取得行j的地址
uchar* data = image.ptr<uchar>(j);
// 遍历当前行每一个元素
for (int i = 0; i < nc; i++) {
// 处理每个元素---------------------
data[i] = cv::saturate_cast<uchar>(
data[i] / div * div + div / 2);
// 元素处理结束---------------------
} // 一行结束
}
}
void getMo(Mat image){
int div = 64;
int nr = image.rows; // 行数
// 每行的元素数量(注意不是像素数量)
int nc = image.cols * image.channels();
for (int j = 0; j < nr; j++) { // 遍历每一行
// 取得行j的地址
uchar* data = image.ptr<uchar>(j);
// 遍历当前行每一个元素
for (int i = 0; i < nc; i++) {
// 处理每个元素---------------------
data[i] = cv::saturate_cast<uchar>(data[i] - data[i] % div + div / 2);
}
}
}
效果: