使用OpenCV2.x计算图像的水平和垂直积分投影
2015-04-21 21:39
966 查看
注:本文参考了wwl33695的一遍博文,地址如下:http://blog.csdn.net/wwl33695/article/details/8566742,
感谢你的支持!
测试图像为lena.jpg,
OK,下面开始积分投影的问题: (
运行环境:VS2012+opencv2.4.10)
1.重要的函数说明:
这个函数初试化一个Mat,所有元素的值均为1.高为src.rows,宽为src.cols ,只有一个通道。
2. adaptiveThreshold(src_gray, src_binary, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY_INV, 25, 10);
阈值化函数,这个的各个参数的含义,就不再详细说明了。主要申明一点:
当第五个参数为:THRESH_BINARY_INV 时:输入的灰度图像就被二值化了,为0或者maxValue(在这里就是255);
3. Mat类中元素的遍历问题:在这里我提供两种基本的方法,网络上的博客关于这个问题有更加详细的办法。
方法一:利用opencv提供的Mat::at 方法解决
比如:
方法二:利用 opencv中的Mat::ptr 方法
比如:
注:这里的代码的有些变量可能不明白,没关系的下面有完整的代码。
4.实现代码1
6.实现代码二(一种相反投影方式)
7.运行结果
8.小结
上面就是我对利用OpenCV2.x完后垂直和水平积分投影的见解,由于刚入门不久,如果有错误或者待修正的地方,请各位可以指出。谢谢!
感谢你的支持!
测试图像为lena.jpg,
OK,下面开始积分投影的问题: (
运行环境:VS2012+opencv2.4.10)
1.重要的函数说明:
[code=c++] Mat paintX = Mat::ones( src.rows, src.cols, CV_8UC1 ); Mat paintY = Mat::ones( src.rows, src.cols, CV_8UC1 );
这个函数初试化一个Mat,所有元素的值均为1.高为src.rows,宽为src.cols ,只有一个通道。
2. adaptiveThreshold(src_gray, src_binary, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY_INV, 25, 10);
阈值化函数,这个的各个参数的含义,就不再详细说明了。主要申明一点:
当第五个参数为:THRESH_BINARY_INV 时:输入的灰度图像就被二值化了,为0或者maxValue(在这里就是255);
3. Mat类中元素的遍历问题:在这里我提供两种基本的方法,网络上的博客关于这个问题有更加详细的办法。
方法一:利用opencv提供的Mat::at 方法解决
比如:
for( i=0; i<src_binary.cols; i++) //列 { for( j=0; j<src_binary.rows; j++) //行 { if( src_binary.at<uchar>( j, i ) == 0) { /*your code*/} } }
方法二:利用 opencv中的Mat::ptr 方法
比如:
for( x=0; x<src_binary.cols; x++) { for(y=0; y<src_binary.rows; y++) { uchar* myptr_v = src_binary.ptr<uchar>(y); //逐行扫描,返回每行的指针 {/*your code */} } }
注:这里的代码的有些变量可能不明白,没关系的下面有完整的代码。
4.实现代码1
#include <iostream> #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include <stdlib.h> #include <stdio.h> using namespace std; using namespace cv; char* wnd_binary = "二值图像"; char* wnd_X = "垂直积分投影"; char* wnd_Y = "水平积分投影"; String imgname = "../lena.jpg"; int main() { Mat src = imread(imgname); Mat src_gray,src_binary,paintX,paintY; //创建两个图像框,用于绘制投影图 (黑底,0 黑, 1 白) paintX = Mat::zeros( src.rows, src.cols, CV_8UC1 ); paintY = Mat::zeros( src.rows, src.cols, CV_8UC1 ); //Mat paintX( src.cols, src.rows, CV_8UC1, Scalar( 0, 0, 0)); //Mat paintY( src.cols, src.rows, CV_8UC1, Scalar( 0, 0, 0)); //转化为灰度图像 cout<<"paintX.cols = "<<paintX.cols<<endl; cout<<"paintX.rows = "<<paintX.rows<<endl; cvtColor(src, src_gray, CV_RGB2GRAY); //二值化图像 adaptiveThreshold(src_gray, src_binary, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY_INV, 25, 10); int* v = new int[src.cols*2]; int* h = new int[src.rows*2]; cout<<"src.cols = "<<src.cols<<endl; cout<<"src.rows = "<<src.rows<<endl; memset(v, 0, src.cols*2); memset(h, 0, src.rows*2); //方法一的实现 /* int i,j; //垂直方向进行累加(积分) for( i=0; i<src_binary.cols; i++) //列 { for( j=0; j<src_binary.rows; j++) //行 { if( src_binary.at<uchar>( j, i ) == 0) //统计的是黑色像素的数量 v[i]++; } } //绘制垂直方向上的投影 for( i=0; i<src_binary.cols; i++) { for( j=0; j<v[i]; j++) { paintX.at<uchar>( j, i ) = 255; //填充白色的像素 } } //水平方向进行累加(积分) for( i=0; i<src_binary.rows; i++) //行 { for( j=0; j<src_binary.cols; j++) //列 { if( src_binary.at<uchar>( i, j ) == 0) //统计黑色像素的数量 h[i]++; } } //绘制水平方向上的投影 for( i=0; i<src_binary.rows; i++) { for( j=0; j<h[i]; j++) { paintY.at<uchar>( i, j ) = 255; //填充白色的像素 } } */ //方法二的实现 int x,y; for( x=0; x<src_binary.cols; x++) { for(y=0; y<src_binary.rows; y++) { uchar* myptr_v = src_binary.ptr<uchar>(y); //逐行扫描,返回每行的指针 if( myptr_v[x] == 0 ) v[x]++; } } for( x=0; x<src_binary.cols; x++) { for(y=0; y<v[x]; y++) { uchar* myptr_x = paintX.ptr<uchar>(y); myptr_x[x] = 255; } } for( x=0; x<src_binary.rows; x++) { uchar* myptr_h = src_binary.ptr<uchar>(x); for(y=0; y<src_binary.cols; y++) { if( myptr_h[y] == 0 ) h[x]++; } } for( x=0; x<src_binary.rows; x++) { uchar* myptr_y = paintY.ptr<uchar>(x); for(y=0; y<h[x]; y++) { myptr_y[y] = 255; } } namedWindow(wnd_binary, CV_WINDOW_AUTOSIZE); namedWindow(wnd_X, CV_WINDOW_AUTOSIZE); namedWindow(wnd_Y, CV_WINDOW_AUTOSIZE); //显示图像 imshow(wnd_binary, src_binary); imshow(wnd_X, paintX); imshow(wnd_Y, paintY); waitKey(0); return 0; }5.运行结果
6.实现代码二(一种相反投影方式)
#include <iostream> #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include <stdlib.h> #include <stdio.h> #include <math.h> using namespace std; using namespace cv; char* wnd_binary = "二值图像"; char* wnd_X = "垂直积分投影"; char* wnd_Y = "水平积分投影"; int main() { Mat src = imread("../lena.jpg"); Mat src_gray,src_binary,paintX,paintY; //创建两个图像框,用于绘制投影图 (设置为白底,0 黑, 1 白) paintX = Mat::ones( src.rows, src.cols, CV_8UC1 ); paintY = Mat::ones( src.rows, src.cols, CV_8UC1 ); cout<<"paintX.cols = "<<paintX.cols<<endl; cout<<"paintX.rows = "<<paintX.rows<<endl; //创建两张白底的图像 for( int row=0; row<src.rows; row++) //行 { for( int col=0; col<src.cols; col++) //列 { paintX.at<uchar>(row, col) = 255; paintY.at<uchar>(row, col) = 255; } } //转化为灰度图像 cvtColor(src, src_gray, CV_RGB2GRAY); //二值化图像 adaptiveThreshold(src_gray, src_binary, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 25, 10); int* v = new int[src.cols*4]; int* h = new int[src.rows*4]; cout<<"src.cols = "<<src.cols<<endl; cout<<"src.rows = "<<src.rows<<endl; memset(v, 0, src.cols*4); memset(h, 0, src.rows*4); int i,j; //方法一遍历 //垂直方向进行累加(积分) for( i=0; i<src_binary.cols; i++) //列 { for( j=0; j<src_binary.rows; j++) //行 { if( src_binary.at<uchar>( j, i ) == 255) //统计的是白色像素的数量 v[i]++; } } //绘制垂直方向上的投影 for( i=0; i<src_binary.cols; i++) { for( j=0; j<v[i]; j++) { paintX.at<uchar>( j, i ) = 0; //填充黑色的像素 } } //水平方向进行累加(积分) for( i=0; i<src_binary.rows; i++) //行 { for( j=0; j<src_binary.cols; j++) //列 { if( src_binary.at<uchar>( i, j ) == 255) //统计白色像素的数量 h[i]++; } } //绘制水平方向上的投影 for( i=0; i<src_binary.rows; i++) { for( j=0; j<h[i]; j++) { paintY.at<uchar>( i, j ) = 0; //填充黑色的像素 } } //方法二遍历 /* int x,y; //垂直积分投影 for( x=0; x<src_binary.cols; x++) { for(y=0; y<src_binary.rows; y++) { uchar* myptr_v = src_binary.ptr<uchar>(y); //逐行扫描,返回每行的指针 if( myptr_v[x] == 255 ) v[x]++; } } for( x=0; x<src_binary.cols; x++) { for(y=0; y<v[x]; y++) { uchar* myptr_x = paintX.ptr<uchar>(y); myptr_x[x] = 0; } } //水平积分投影 for( x=0; x<src_binary.rows; x++) { uchar* myptr_h = src_binary.ptr<uchar>(x); for(y=0; y<src_binary.cols; y++) { if( myptr_h[y] == 255 ) h[x]++; } } for( x=0; x<src_binary.rows; x++) { uchar* myptr_y = paintY.ptr<uchar>(x); for(y=0; y<h[x]; y++) { myptr_y[y] = 0; } } */ namedWindow(wnd_binary, CV_WINDOW_AUTOSIZE); namedWindow(wnd_X, CV_WINDOW_AUTOSIZE); namedWindow(wnd_Y, CV_WINDOW_AUTOSIZE); //显示图像 imshow(wnd_binary, src_binary); imshow(wnd_X, paintX); imshow(wnd_Y, paintY); waitKey(0); return 0; }
7.运行结果
8.小结
上面就是我对利用OpenCV2.x完后垂直和水平积分投影的见解,由于刚入门不久,如果有错误或者待修正的地方,请各位可以指出。谢谢!
相关文章推荐
- 使用OpenCV2.x计算图像的水平和垂直积分投影
- opencv学习---计算图像的水平积分投影和垂直积分投影
- 【OpenCV】计算图像的水平和垂直积分投影
- 利用OpenCV计算图像的垂直和水平积分投影
- 利用OpenCV计算图像的垂直和水平积分投影
- 利用OpenCV计算图像的垂直和水平积分投影
- opencv学习---计算图像的水平积分投影和垂直积分投影
- 图像的水平与垂直积分投影
- 使用opencv作物件识别(一) —— 积分直方图加速HOG特征计算
- javacpp-opencv图像处理3:使用opencv原生方法遍历摄像头设备及调用(增加实时帧率计算方法)
- javacpp-opencv图像处理3:使用opencv原生方法遍历摄像头设备及调用(增加实时帧率计算方法)
- 使用opencv作物件识别(一) —— 积分直方图加速HOG特征计算
- 如何理解图像像素点在水平方向和垂直的投影呢?
- 使用opencv作物件识别(一) —— 积分直方图加速HOG特征计算
- 用OpenCV实现图像的水平镜像(翻转)变换和竖直镜像(翻转)变换(垂直镜像变换)的源码
- OpenCV2.4.13 文本分割(水平垂直,直方图投影)
- OpenCV之imgproc 模块. 图像处理(4)直方图均衡化 直方图计算 直方图对比 反向投影 模板匹配
- 学习opencv,使用反向块投影搜索图像中物体的位置cvCalcBackProjectPatch
- 使用opencv作物件识别(一) —— 积分直方图加速HOG特征计算
- 对OpenCV mat进行水平和垂直方向的投影