opencv字元分割
阿新 • • 發佈:2019-01-10
投影法
#include<iostream> #include <opencv2/opencv.hpp> #include <stdio.h> using namespace std; using namespace cv; //************************************************************************************ Mat vertical_projection(Mat & input_src, Mat src) //輸入二值化圖片 { /**************統計原圖片中每列白色畫素數目******************************/ int src_width = input_src.cols; int src_height = input_src.rows; int* col_array = new int[src_width]();//建立用於儲存每列白色畫素個數的陣列 //memset(col_array, 0, src_width*4);//初始化陣列 //取列白色畫素個數 for (int i = 0; i < src_height; i++){ for (int j = 0; j < src_width; j++){ if (input_src.at<uchar>(i, j)){ col_array[j]++; } } } /**************將每列白色畫素數目繪製成直方圖***************************/ //定義畫布 繪製垂直投影下每列白色畫素的數目 Mat draw_col(src_height, src_width, CV_8UC1, Scalar(0)); for (int i = 0; i< src_width; i++){ for (int j = 0; j < col_array[i]; j++){ draw_col.at<uchar>(src_height-j-1,i) = 255; } } imshow("draw_col", draw_col); /**************統計原圖片中每行白色畫素數目******************************/ int* row_array = new int[src_height]();//建立用於儲存每行白色畫素個數的陣列 //memset(row_array, 0, src_width*4);//初始化陣列 //取列白色畫素個數 for (int i = 0; i < src_height; i++){ for (int j = 0; j < src_width; j++){ if (input_src.at<uchar>(i, j)){ row_array[i]++; } } } /**************將每行白色畫素數目繪製成直方圖***************************/ //定義畫布 繪製垂直投影下每行白色畫素的數目 Mat draw_row(src_height, src_width, CV_8UC1, Scalar(0)); for (int i = 0; i< src_height; i++){ for (int j = 0; j < row_array[i]; j++){ draw_row.at<uchar>(i,src_width-j-1) = 255; } } imshow("draw_row", draw_row); /*********根據每列白色畫素數目設定擷取起始和截止列***********************/ //定義Mat vector ,儲存圖片組 vector<Mat> split_src; //定義標誌,用來指示在白色畫素區還是在全黑區域 bool white_block_col = 0, black_block_col = 0; //定義列temp_col_forword temp_col_behind,記錄字元擷取起始列和截止列 int temp_col_forword=0,temp_col_behind = 0; Mat split_temp; vector<int> col_begin; vector<int> col_end; //遍歷陣列col_array for (int i = 0; i < src_width; i++){ if (col_array[i]){//表示區域有白色畫素 white_block_col = 1; black_block_col = 0; } else{ //若無白色畫素(進入黑色區域) if (white_block_col == 1){//若前一列有白色畫素 temp_col_behind = i;//取當前列為截止列 ////擷取下一部分 //input_src(Rect(temp_col_forword, 0, temp_col_behind - temp_col_forword, src_height)).copyTo(split_temp); //split_src.push_back(split_temp); col_begin.push_back(temp_col_forword); col_end.push_back(temp_col_behind); } temp_col_forword = i;//記錄最新黑色區域的列號,記為起始列 black_block_col = 1;//表示進入黑色區域 white_block_col = 0; } } //遍歷陣列row_array vector<int> row_begin; vector<int> row_end; bool white_block_row = 0, black_block_row = 0; int temp_row_forword=0, temp_row_behind = 0; for (int i = 0; i < src_height; i++){ if (row_array[i]){//表示區域有白色畫素 white_block_row = 1; black_block_row = 0; } else{ //若無白色畫素(進入黑色區域) if (white_block_row == 1){//若前一列有白色畫素 temp_row_behind = i;//取當前列為截止列 ////擷取下一部分 //input_src(Rect(temp_col_forword, 0, temp_col_behind - temp_col_forword, src_height)).copyTo(split_temp); //split_src.push_back(split_temp); row_begin.push_back(temp_row_forword); row_end.push_back(temp_row_behind); } temp_row_forword = i;//記錄最新黑色區域的列號,記為起始列 black_block_row = 1;//表示進入黑色區域 white_block_row = 0; } } vector<Mat> segmentation; for (unsigned int j = 0; j < col_end.size(); j++) { Mat temp = src(Range(row_begin[0] + 800,row_end[0] + 800), Range(col_begin[j] + 650, col_end[j] + 650)); segmentation.push_back(temp); } for (unsigned int j = 3; j < col_end.size() - 2; j++) { Mat temp = src(Range(row_begin[1] + 800,row_end[1] + 800), Range(col_begin[j] + 650, col_end[j] + 650)); segmentation.push_back(temp); } for (unsigned int i = 0 ; i < segmentation.size(); i++) { string s = to_string(i + 1); //imshow(s, segmentation[i]); string filename = "F:\\分割圖片\\4\\" + s + ".bmp"; imwrite(filename, segmentation[i]); } waitKey(0); return input_src; } int main() { Mat src = imread("F:\\PIN_LENGTH\\4.bmp"); Mat roi = src(Range(800,1200), Range(650,1600)); Mat roi_gray; cvtColor(roi, roi_gray, CV_BGR2GRAY, 1); //轉換為單通道 Mat roi_gray_blur; blur(roi_gray, roi_gray_blur, Size(3,3)); //濾波 Mat roi_gray_blur_thresh; threshold(roi_gray_blur, roi_gray_blur_thresh, 200, 255, THRESH_BINARY_INV); //二值化 imshow("canny", roi_gray_blur_thresh); vertical_projection(roi_gray_blur_thresh , src); /*imshow("sdf", roi); namedWindow("src", WINDOW_NORMAL); imshow("src", src);*/ waitKey(0); }