效果展示
白色=255
黑色=0
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main()
{
Mat srcImage = imread("photo/number.png");//原图
Mat srcGray; cvtColor(srcImage, srcGray, COLOR_RGB2GRAY);//灰度图像
Mat input_src; threshold(srcGray, input_src, 0, 255, THRESH_BINARY_INV); //二值化图像
int width = input_src.cols;//列数
int height = input_src.rows;//行数
int* whitesum = new int[width]();//创建存储每列白色出现次数的数组指针
for (int i = 0; i < height; i++)//遍历行
{
for (int j = 0; j < width; j++)//遍历列
{
if (input_src.at<uchar>(i, j) == 255)//判断是否为白色
{
whitesum[j]++;//统计每列的白色总数
}
}
}
Mat out(height, width, CV_8UC1, Scalar(0));//创建一个全黑的大小相等的单通道图
for (int i = 0; i < width; i++)//遍历列
{
for (int j = 0; j < whitesum[i]; j++)//遍历行,退出条件为画完白色
{
out.at<uchar>(height - j - 1, i) = 255;//绘制每一列的白色次数投影图
}
}
imshow("原图", srcImage);
imshow("二值化图像", input_src);
imshow("投影图", out);
Mat img;//切割图像
bool white = 0;//判断值
int a = 0, b = 0;//切割图像的开始值和末尾值
for (int i = 0; i < width; i++)//遍历列
{
if (whitesum[i])//判断每一列是否为白色
{
white = 1;//出现白色
}
else//黑色
{
if (white == 1)//如果之前那列出现白色
{
b = i;//末尾值
rectangle(srcImage, Point(a, height), Point(b, 0), Scalar(100, 0, 255), 2, 1, 0);//画切割边框
img = input_src(Rect(a, 0, b - a, height)).clone();//切割图
imshow("切割边框图", srcImage);
imshow("切割图", img);
waitKey(0);
}
a = i;//起始值
white = 0;//没有出现白色
}
}
waitKey(0);
return 0;
}