灰度图像与二值化
问题描述:将彩色图像转换为灰度图像并进行二值化处理
代码如下(示例):
#include <opencv2/opencv.hpp>
cv::Mat BGR2GRAY(cv::Mat img)
{
int width = img.cols;
int height = img.rows;
// CV_8UC1代表单通道的8bit array数组
cv::Mat new_image = cv::Mat::zeros(height, width, CV_8UC1);
for (int i = 0; i < height; ++i){
for (int j = 0; j < width; ++j){
// 转换公式 img_gray = 0.2126 * R + 0.7152 * G + 0.0722 * B;
// 需要注意图像格式输出的是整数
new_image.at<uchar>(i, j) = 0.2126 * (float)img.at<cv::Vec3b>(i, j)[2]\
+ 0.7152 * (float)img.at<cv::Vec3b>(i, j)[1]\
+ 0.0722 * (float)img.at<cv::Vec3b>(i, j)[0];
}
}
return new_image;
}
cv::Mat Binarize(cv::Mat img, int thres)
{
int width = img.cols;
int height = img.rows;
cv::Mat new_image = cv::Mat::zeros(height, width, CV_8UC1);
for (int i = 0; i < height; ++i){
for (int j = 0; j < width; ++j){
if (img.at<uchar>(i, j) > thres)
{
new_image.at<uchar>(i, j) = 255;
}
else
{
img.at<uchar>(i, j) = 0;
}
}
}
return new_image;
}
int main()
{
cv::Mat img = cv::imread("../Neopolitan.png", cv::IMREAD_COLOR);
// BGR2GRAY
cv::Mat gray_image = BGR2GRAY(img);
cv::Mat new_image = Binarize(gray_image, 128);
cv::imwrite("../1-10/Neopolitan2.png", gray_image);
cv::imwrite("../1-10/Neopolitan3.png", new_image);
cv::waitKey(0);
cv::destroyAllWindows();
return 0;
}
输入图像 (Neopolitan.png) | 灰度图像 (Neopolitan2.png) | 二值化图像 (Neopolitan3.png) |
---|---|---|
![]() | ![]() | |
![]() |
Vec3b
Vec3b
可以看作是vector<uchar, 3>
,简单而言就是一个uchar类型的,长度为3的vector向量。
由于在OpenCV中,使用imread读取到的Mat图像数据,都是用uchar类型的数据存储,对于RGB三通道的图像,每个点的数据都是一个Vec3b类型的数据。使用at定位方法如下:
img.at<Vec3b>(row, col)[0] = 255; // 这是指修改B通道数据
img.at<Vec3b>(row, col)[1] = 255; // 这是指修改G通道数据
img.at<Vec3b>(row, col)[2] = 255; // 这是指修改R通道数据