3.1 绘制直方图
//*************************************************************************************
// 函数名称 绘制图像直方图
// 参数说明 image 图像原数组
// 参数说明 hist_scale 要绘制的直方图单个矩形宽
// 参数说明 hist_scale 要绘制的直方图高
// 返回参数 double 图像阈值
// 备注信息 按空格退出
//*************************************************************************************
double img_show_hist(cv::Mat image, int hist_scale, int hist_height, int histSize)
{
float range[] = { 0, 256 }; // 像素值的范围
float bin_val, threshold ;
int intensity;
const float* histRange = { range };
double max_val, min_val, peak_val = 0;
cv::Point min_loc, max_loc;
// 计算直方图
cv::Mat hist;
cv::calcHist(&image, 1, 0, cv::Mat(), hist, 1, &histSize, &histRange, true, false);
for (int i = 0; i < hist.rows; ++i) {
float bin_val = hist.at<float>(i);
std::cout << "Bin " << i << ": " << bin_val << std::endl;
}
//创建一个黑底的8位的3通道图像,高256,宽256*2
Mat hist_img(hist_height, 256 * hist_scale, CV_8UC3, Scalar(0, 0, 0));
//归一化处理
normalize(hist, hist, 0, hist_height, NORM_MINMAX, -1, Mat());
//计算直方图的最大像素值
minMaxLoc(hist, &min_val, &max_val, &min_loc, &max_loc);
//遍历直方图得到的数据
for (int i = 0; i < 256; i++)
{
bin_val = hist.at<float>(i); //遍历hist元素(注意hist中是float类型)
intensity = cvRound(bin_val * hist_height / max_val); //绘制高度
rectangle(hist_img,
Point(i * hist_scale, hist_height - 1),
Point((i + 1) * hist_scale - 1,
hist_height - intensity),
Scalar(255, 255, 255));
//简单地图片杂色干扰过滤,输出阈值
if (bin_val > peak_val && i > 3)
{
peak_val = bin_val;
threshold = i;
}
}
//显示直方图
cv::imshow("hist", hist_img);
std::string name = "hist";
while (waitKey(1) != ' ');
cv::destroyAllWindows();
std::cout << "threshold = " << threshold << endl;
return threshold;
}
3.2 P-tile法处理灰度图像
//*************************************************************************************
// 函数名称 P_Tile图像二值化处理
// 参数说明 gray 灰度图像原数组
// 备注信息
//*************************************************************************************
int P_Tile_Extract(Mat gray)
{
// 计算前景占比
int totalPixels = gray.rows * gray.cols;
int foregroundPixels = cv::countNonZero(gray);
double percentage = static_cast<double>(foregroundPixels) / totalPixels * 100.0;
//计算直方图
std::cout << "percentage = " << percentage << endl;
std::cout << "Number of channels: " << gray.channels() << endl;
std::cout << "Image size: " << gray.size() << endl;
float range[] = { 0, 256 }, bin_val, threshold;
int histSize = 256;
const float* histRange = { range };
cv::Mat hist;
cv::calcHist(&gray, 1, 0, cv::Mat(), hist, 1, &histSize, &histRange, true, false);
// P_Tile图像二值化处理
int amount = 0, sum = 0;
for (int y = 0; y < hist.rows; y++)
amount += hist.at<float>(y);
int y;
for (y = 0; y < hist.rows; y++)
{
sum += hist.at<float>(y);
if (sum >= amount * percentage / 100) break;
}
std::cout << "amount = " << amount << endl;
std::cout << "sum = " << sum << endl;
std::cout << "y = " << y << endl;
return y;
}
3.3 大津法处理灰度图像
3.3.1 彩色图像转灰度图像
//显示灰度图像
cv::Mat gray;
cv::cvtColor(im, gray, cv::COLOR_BGR2GRAY);
cv::imshow("gray", gray);
while (waitKey(1) != ' ');
cv::destroyAllWindows();
3.3.2 大津法处理灰度图像
// 大津法处理二值化图像
cv::Mat dst;
cv::threshold(gray, dst, 0, 255, THRESH_OTSU);
cv::imshow("dst", dst);
std::string name = "大津法";
save_image(dst, root, name);
while (waitKey(1) != ' ');
cv::destroyAllWindows();
3.4 局部自适应法处理灰度图像
/ 局部自适应二值化图像处理
Mat src_binary;
adaptiveThreshold(~gray, src_binary, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 11, -2);
cv::imshow("src_binary", src_binary);
name = "局部自适应";
save_image(src_binary, root, name);
while (waitKey(1) != ' ');
cv::destroyAllWindows();
3.5 直方图计算图像阈值,处理灰度图像
// 绘制图像直方图
double max_val = img_show_hist(gray, 4, 256, 256);
//显示二值图像
cv::cvtColor(im, gray, cv::COLOR_BGR2GRAY);
cv::threshold(gray, binary_gray, max_val, 256, THRESH_BINARY);
cv::imshow("binary_gray", binary_gray);
while (waitKey(1) != ' ');
cv::destroyAllWindows();
3.6 保存所需图像
//*************************************************************************************
// 函数名称 保存图像
// 参数说明 img 图像原数组
// 参数说明 &file_root 生成文件目录
// 参数说明 string &name 生成文件名称
// 返回参数 void
// 备注信息
//使用示例 std::string name = "gray_img"; save_image(gray, root, name);
//*************************************************************************************
/* 创建处理图像BMP文件 */
#define ENABLE_MAKE_IMG (1)
void save_image(Mat img, const string& file_root, string& name)
{
#if ENABLE_MAKE_IMG
// 生成文件名
std::string extract_path = file_root + "/" + name + ".bmp";
// 保存图像
cv::imwrite(extract_path, img);
#endif
}
3.7 实验数据记录(以图2-1为例)
图3- 1 绘制直方图
图3- 2 P-tile法处理灰度图像
图3- 3 大津法处理灰度图像
图3- 4 局部自适应法处理灰度图像
图3- 5 直方图计算图像阈值,处理灰度图像