灰度图像与二值化
问题描述:将彩色图像转换为灰度图像并进行二值化处理
代码如下(示例):
#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;
}
cv::Mat Binarize_Otsu(cv::Mat img)
{
int width = img.cols;
int height = img.rows;
double count0 = 0, count1 = 0;
double sum_val0 = 0, sum_val1 = 0;
double sigma_max = 0, sigma = 0;
int thres = 0;
int val = 0;
for (int th = 0; th < 255; ++th)
{
for (int i = 0; i < height; ++i)
{
count0 = 0; // 每次循环重置参数
count1 = 0;
sum_val0 = 0;
sum_val1 = 0;
for (int j = 0; j < width; ++j)
{
val = (int)img.at<uchar>(i, j);
if (val < th)
{
count0++;
sum_val0 += val;
}
else
{
count1++;
sum_val1 += val;
}
}
}
sum_val0 /= count0;
sum_val1 /= count1;
count0 /= (height * width);
count1 /= (height * width);
sigma = count0 * count1 * pow((sum_val0 - sum_val1), 2);
if (sigma > sigma_max)
{
sigma_max = sigma;
thres