1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 图像水平投影和垂直投影 图像分割

图像水平投影和垂直投影 图像分割

时间:2021-02-22 09:34:25

相关推荐

图像水平投影和垂直投影 图像分割

图像水平投影和垂直投影,图像分割

// opencv.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。////#pragma comment(lib , "D:/OpenCV4.5.1/opencv/build/x64/vc15/lib/opencv_world451d.lib")//#pragma comment(lib , "D:/OpenCV4.5.1/opencv/newbuild_64/install/x64/vc15/lib/opencv_world451d.lib")#include <iostream>#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/opencv.hpp>#include <fstream>#include <opencv2/ml.hpp>#include <cmath>#include <locale>#include <codecvt>#include <string>using namespace cv;using namespace std;using namespace ml;//积分二值化void thresholdIntegral(Mat inputMat, Mat& outputMat){int nRows = inputMat.rows;int nCols = inputMat.cols;// 创建积分图Mat sumMat;integral(inputMat, sumMat);//把图分成8份 (n份)int S = MAX(nRows, nCols) / 8;double T = 0.15;//int s2 = S / 2;int x1, y1, x2, y2, count, sum;int* p_y1, *p_y2;uchar* p_inputMat, *p_outputMat;for (int i = 0; i < nRows; ++i){//找行的范围y1 = i - s2;y2 = i + s2;if (y1 < 0){y1 = 0;}if (y2 >= nRows){y2 = nRows - 1;}//取出区域行的左上角和左下角p_y1 = sumMat.ptr<int>(y1);p_y2 = sumMat.ptr<int>(y2);//取出图像某行的像素值p_inputMat = inputMat.ptr<uchar>(i);p_outputMat = outputMat.ptr<uchar>(i);for (int j = 0; j < nCols; ++j){//找列的范围// 设置 SxS 区域x1 = j - s2;x2 = j + s2;if (x1 < 0){x1 = 0;}if (x2 >= nCols){x2 = nCols - 1;}//区域内像素的个数count = (x2 - x1)* (y2 - y1);//获取区域内像素个数的 累加的像素值// I(x,y)=s(x2,y2)-s(x1,y2)-s(x2,y1)+s(x1,x1)sum = p_y2[x2] - p_y1[x2] - p_y2[x1] + p_y1[x1];//如果图像的当前像素值低于区域内的平均像素值(加权:在这里是0.85) 设为0if ((int)(p_inputMat[j] * count) < (int)(sum* (1.0 - T))){p_outputMat[j] = 0;}else{p_outputMat[j] = 255;}}}}//垂直方向投影void picshadowx(Mat binary, vector<Mat> &result){Mat paintx(binary.size(), CV_8UC1, Scalar(255)); //创建一个全白图片,用作显示int* blackcout = new int[binary.cols];memset(blackcout, 0, binary.cols * 4);for (int i = 0; i < binary.rows; i++){for (int j = 0; j < binary.cols; j++){if (binary.at<uchar>(i, j) == 0){blackcout[j]++; //垂直投影按列在x轴进行投影}}}for (int i = 0; i < binary.cols; i++){for (int j = 0; j < blackcout[i]; j++){paintx.at<uchar>(binary.rows - 1 - j, i) = 0; //翻转到下面,便于观看}}imshow("paintx", paintx);int startindex = 0;int endindex = 0;bool inblock = false; //是否遍历到字符位置for (int i = 0; i < paintx.cols; i++){if (!inblock&&blackcout[i] != 0) //进入有字符区域{inblock = true;startindex = i;cout << "startindex:" << startindex << endl;}if (inblock&&blackcout[i] == 0) //进入空白区{endindex = i;inblock = false;Mat roi = binary.colRange(startindex, endindex + 1); //从而记录从开始到结束列的位置,即可进行行切分result.push_back(roi);}}delete blackcout;}//水平方向投影并行分割void picshadowy(Mat binary,vector<Mat> &result){//是否为白色或者黑色根据二值图像的处理得来Mat painty(binary.size(), CV_8UC1, Scalar(255)); //初始化为全白//水平投影int* pointcount = new int[binary.rows]; //在二值图片中记录行中特征点的个数memset(pointcount, 0, binary.rows * 4);//注意这里需要进行初始化for (int i = 0; i < binary.rows; i++){for (int j = 0; j < binary.cols; j++){if (binary.at<uchar>(i, j) == 0){pointcount[i]++; //记录每行中黑色点的个数 //水平投影按行在y轴上的投影}}}for (int i = 0; i < binary.rows; i++){for (int j = 0; j < pointcount[i]; j++) //根据每行中黑色点的个数,进行循环{painty.at<uchar>(i, j) = 0;}}imshow("painty", painty);int startindex = 0;int endindex = 0;bool inblock = false; //是否遍历到字符位置for (int i = 0; i < painty.rows; i++){if (!inblock&&pointcount[i] != 0) //进入有字符区域{inblock = true;startindex = i;cout << "startindex:" << startindex << endl;}if (inblock&&pointcount[i] == 0) //进入空白区{endindex = i;inblock = false;Mat roi = binary.rowRange(startindex, endindex + 1); //从而记录从开始到结束行的位置,即可进行行切分result.push_back(roi);}}delete pointcount;}int main(int argc, char* argv[]){Mat src = cv::imread("test_number.jpg");if (src.empty()){cerr << "Problem loading image!!!" << endl;return -1;}imshow("in", src);Mat gray;if (src.channels() == 3){cv::cvtColor(src, gray,COLOR_BGR2GRAY);}else{gray = src;}Mat bw2 = Mat::zeros(gray.size(), CV_8UC1);thresholdIntegral(gray, bw2);cv::imshow("binary integral", bw2);vector<Mat> result;picshadowy(bw2, result);for (int i = 0; i < result.size(); i++){vector<Mat> result1;picshadowx(result[i], result1);for (int j = 0; j < result1.size(); j++){Mat tmp = result1[j];imshow("test" + to_string(i) + to_string(j), tmp);}}waitKey(0);return 0;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。