OpenCV中图像的像素是以矩阵的形式储存,矩阵中的每一个元素代表一个像素,使用cv::Mat储存图像的像素。
图像遍历
下面介绍两种图像遍历方法:
方法一:指针遍历图像(最高效)
#include "pch.h"
#include <core.hpp>
#include <highgui.hpp>
#include <imgproc.hpp>
using namespace std;
using namespace cv;
void colorReduce(cv:: Mat& img, int div=64)
{
int nr = img.rows; //图像像素的行数
int nl = img.cols*img.channels(); //每行元素的个数
int n = static_cast<int>(log(static_cast<double>(div)) / log(2.0));
uchar mask = 0xFF << n; //对图像每个像素掩膜操作
for (int i = 0; i < nr; i++)
{
uchar* data = img.ptr<uchar>(i);
for (int j = 0; j < nl; j++)
{
*data++ = (*data & mask) + div / 2; // +div/2为了取像素范围值的中间,使各个像素值偏差不会太大
}
}
}
int main()
{
Mat img= imread("D:\\Visual Studio project\\ConsoleApplication2\\风景.jpg");
namedWindow("原始图", 0);
resizeWindow("原始图", 512, 512);
imshow("原始图", img);
colorReduce(img);
namedWindow("遍历图", 0);
resizeWindow("遍历图", 512, 512);
imshow("遍历图",img);
waitKey(0);
}
输出结果:
方法二:数组遍历图像
#include "pch.h"
#include <core.hpp>
#include <highgui.hpp>
#include <imgproc.hpp>
using namespace std;
using namespace cv;
void colorReduce(cv::Mat &image, int div = 64)
{
int nr = image.rows;
int nl= image.cols;
for (int j=0; j<nr; j++)
{
for (int i=0; i<nl; i++)
{
image.at<cv::Vec3b>(j,i)[0]=image.at<cv::Vec3b>(j,i)[0]/div*div + div/2;
image.at<cv::Vec3b>(j,i)[1]=image.at<cv::Vec3b>(j,i)[1]/div*div + div/2;
image.at<cv::Vec3b>(j,i)[2]=image.at<cv::Vec3b>(j,i)[2]/div*div + div/2;
}
}
}
int main()
{
Mat img= imread("D:\\Visual Studio project\\ConsoleApplication2\\风景.jpg");
namedWindow("原始图", 0);
resizeWindow("原始图", 512, 512);
imshow("原始图", img);
colorReduce(img);
namedWindow("遍历图", 0);
resizeWindow("遍历图", 512, 512);
imshow("遍历图",img);
waitKey(0);
}
输出结果:
图像截取:
利用Rect函数,该函数使用格式为:Rect(x,y,width,height);
x表示图片左上角顶点的x坐标
y表示图片左上角顶点的y坐标
width表示截取图像的宽度
height表示截取图像的高度
#include "pch.h"
#include <core.hpp> //包含了opencv的基本数据结构
#include <highgui.hpp> //图像交互界面
#include <imgproc.hpp> //图像的变换,滤波直方图
using namespace std;
using namespace cv;
int main()
{
Mat img = imread("D:\\Visual Studio project\\ConsoleApplication2\\风景.jpg");
Rect rect(100, 40, 1000, 400); //图片的左上角坐标为(100,40)
Mat ROI = img(rect);
imshow("截取图", ROI);
waitKey(0);
}
输出结果: