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

// 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;
}

图像水平投影和垂直投影,图像分割相关推荐

  1. opencv计算图像的水平投影和垂直投影

    本文介绍使用opencv实现计算一幅图像的水平投影和垂直投影,代码如下: class HorizontalProjection { private:int maxLine;//255最大行位置int ...

  2. [机器视觉]gocv图像水平投影和垂直投影

    文章目录 1. 水平投影和垂直投影 2. 投影原理 3. 代码实现 1. 水平投影和垂直投影 图像水平投影和垂直投影效果如下图所示: 原图: 水平投影: 垂直投影: 2. 投影原理 投影原理很简单,比 ...

  3. opencv java水平投影_使用OpenCv中Mat进行水平投影与垂直投影并实现字符切分

    由于要做图像的处理,所以最近在学习Opencv的相关知识,学习了Opencv中的Mat对象,查阅了网上的资料,了解了相关知识.现在实现了一个使用Mat对象来进行图像的水平投影与垂直投影,并在此基础之上 ...

  4. OpenCV 实现图片的水平投影与垂直投影,并进行行分割

    前言:对于印刷体图片来说,进行水平投影和垂直投影可以很快的进行分割,本文在OpenCV中如何进行水平投影和垂直投影通过代码进行说明. 水平投影:二维图像在y轴上的投影 垂直投影:二维图像在x轴上的投影 ...

  5. matlab 水平投影,matlab图像处理方面的问题。水平投影和垂直投影!

    我在本论坛找了一个程序: I=imread('mp23.jpg'); I1=rgb2gray(I);                  %转换成灰度图像 Imax=double(max(max(I1) ...

  6. 用OpenCv中Mat进行水平投影与垂直投影并实现字符切分

    目前即将开始的一个新项目是进行字符识别,下面就使用水平投影机垂直投影的测试代码贴出,供大家参考. #include<iostream> #include<opencv2\highgu ...

  7. OpenCV mat类实现水平投影和垂直投影

    图像经过灰度化和otsu阈值分割,分别绘制水平和垂直投影 #include<iostream> #include <cv.h> #include <highgui.h&g ...

  8. 基于水平投影,垂直投影的字符图像分割思路和代码实现

    http://blog.csdn.net/u010910436/article/details/40399437 首先介绍算法思路:图像对应方向的投影,就是在该方向取一条直线,统计垂直于该直线(轴)的 ...

  9. python字符垂直输出型烟雾机_python+opencv实现水平投影和垂直投影

    import cv2 import numpy as np from matplotlib import pyplot as plt img=cv2.imread('C:\\Users\\Lenovo ...

最新文章

  1. ASP.NET 应用程序生命周期概述
  2. url的三个js编码函数escape(),encodeURI(),encodeURIComponent()简介【转】
  3. VC++ error C2248: “CObject::CObject”: 无法访问 private 成员(在“CObject”类中声明)
  4. cookie被淘汰_session正在被淘汰吗?
  5. Deep Learning运行所需的硬件配置(转)
  6. c++函数返回二维数组_C++ 怎样让函数返回数组
  7. ASP.Net学习笔记012--12ViewState初探
  8. 5G 会榨干手机的电池?
  9. 《Linux启动过程分析》内核挂载根文件系统
  10. 手写基于NIO的迷你版tomcat
  11. Matlab UIAxes中添加图例
  12. linux opencv调用笔记本摄像头,Linux下利用Opencv打开笔记本摄像头问题
  13. 服务器是什么?服务器的作用与用途
  14. K210入门,用wifi通讯
  15. C语言正弦和余弦的值
  16. 什么是.NET的程序集?
  17. 费马大定理n=3时的欧拉证明,x^3+y^3=z^3无xyz≠0的整数解
  18. 为什么冠状病毒从湖北出发传播这么快?
  19. 高效学习方法和工具推荐,让你事半功倍!
  20. 计算机主板上的cmos芯片的主要用途是,cmos芯片的作用及主要用途

热门文章

  1. Android 5.1高通方案增加GPIO按键
  2. Ae效果控件快速参考:风格化
  3. 【办公类-16-05-01】“2022上学期 大班游戏活动室排班表——班主任版21周”(python 排班表系列)
  4. 最长单调递增子序列(时间复杂度O(nlogn))
  5. 三维体数据分割算法及实现
  6. delphi2010 开发及调试WebService 实例
  7. python 游戏辅助lol_绝地助手_(Python基础教程之八)Python中的list操作
  8. android 6.0 tv,最强安卓机顶盒Shield TV升级安卓6.0系统,还支持了Vulkan
  9. Python从入门到入魔 葵花宝典指南分享
  10. 闪讯利用openwrt路由器拨号教程(二)