测试图像为lena.jpg,
OK,下面开始积分投影的问题: ( 运行环境:VS2012+opencv2.4.10)
1.重要的函数说明:
- <textarea readonly="readonly" name="code" class="c++" style="margin: 0px; width: 812px; height: 55px;">
- Mat paintX = Mat::ones( src.rows, src.cols, CV_8UC1 );
- Mat paintY = Mat::ones( src.rows, src.cols, CV_8UC1 );
- </textarea>
这个函数初试化一个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)
- { }
- }
- }
方法二:利用 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);
- {}
- }
- }
注:这里的代码的有些变量可能不明白,没关系的下面有完整的代码。
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;
-
-
- paintX = Mat::zeros( src.rows, src.cols, CV_8UC1 );
- paintY = Mat::zeros( src.rows, src.cols, CV_8UC1 );
-
-
-
-
- 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 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;
-
- 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;
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 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完后垂直和水平积分投影的见解,由于刚入门不久,如果有错误或者待修正的地方,请各位可以指出。谢谢!