首页 > 搜索 > 积分图的算法,【OpenCV 4】图像积分图算法:integral()

积分图的算法,【OpenCV 4】图像积分图算法:integral()

互联网 2020-10-29 02:08:52
在线算命,八字测算命理

目录

一、编程环境

二、图像积分图算法

三、程序说明

四、示例程序

五、运行效果

一、编程环境 OpenCV 4.1.0IDEVisual Studio 2017 Enterprise (15.9.19)操作系统Windows 10 x64 中文专业版 (1909)二、图像积分图算法

        积分图像是Crow在1984年首次提出,是为了在多尺度透视投影中提高渲染速度,是一种快速计算图像区域和与平方和的算法。其核心思想是对每个图像建立自己的积分图查找表,在图像积分处理计算阶段根据预先建立的积分图查找表,直接查找从而实现对均值卷积线性时间计算,做到了卷积执行的时间与半径窗口大小的无关联。

        图像积分图在图像特征提取HAAR/SURF、二值图像分析、图像相似相关性NCC计算、图像卷积快速计算等方面均有应用,是图像处理中的经典算法之一。

 

三、程序说明 OpenCV 中的 integral()函数:void integral( InputArray src, OutputArray sum, OutputArray sqsum, int sdepth = -1, int sqdepth = -1 ); 参数说明:

src:输入图像。

sum: 和表。

sqsum: 平方和表。

sdepth: 和表数据深度(CV_32S, CV_32F, or CV_64F)。

sqdepth: 平方和表数据深度(CV_32S, CV_32F, or CV_64F)。

 

四、示例程序 #include #include using namespace cv;using namespace std;void blur_demo(Mat &image, Mat &sum);void edge_demo(Mat &image, Mat &sum);int getblockSum(Mat &sum, int x1, int y1, int x2, int y2, int i);int main(int argc, char* argv[]) {Mat src = imread("../images/test.jpg");if (src.empty()) {printf("不能打开图像!\n");return -1;}namedWindow("input", WINDOW_AUTOSIZE);imshow("input", src);// 计算积分图Mat sum, sqrsum;integral(src, sum, sqrsum, CV_32S, CV_32F);// 积分图应用edge_demo(src, sum);blur_demo(src, sum);waitKey(0);return 0;}void blur_demo(Mat &image, Mat &sum) {int w = image.cols;int h = image.rows;Mat result = Mat::zeros(image.size(), image.type());int x2 = 0, y2 = 0;int x1 = 0, y1 = 0;int ksize = 5;int radius = ksize / 2;int ch = image.channels();int cx = 0, cy = 0;for (int row = 0; row < h + radius; row++) {y2 = (row + 1) > h ? h : (row + 1);y1 = (row - ksize) < 0 ? 0 : (row - ksize);for (int col = 0; col < w + radius; col++) {x2 = (col + 1) > w ? w : (col + 1);x1 = (col - ksize) < 0 ? 0 : (col - ksize);cx = (col - radius) < 0 ? 0 : col - radius;cy = (row - radius) < 0 ? 0 : row - radius;int num = (x2 - x1)*(y2 - y1);for (int i = 0; i < ch; i++) {// 积分图查找和表,计算卷积int s = getblockSum(sum, x1, y1, x2, y2, i);result.at(cy, cx)[i] = saturate_cast(s / num);}}}imshow("blur_demo", result);}/*** 3x3 sobel 垂直边缘检测演示*/void edge_demo(Mat &image, Mat &sum) {int w = image.cols;int h = image.rows;Mat result = Mat::zeros(image.size(), CV_32SC3);int x2 = 0, y2 = 0;int x1 = 0, y1 = 0;int ksize = 3; // 算子大小,可以修改,越大边缘效应越明显int radius = ksize / 2;int ch = image.channels();int cx = 0, cy = 0;for (int row = 0; row < h + radius; row++) {y2 = (row + 1) > h ? h : (row + 1);y1 = (row - ksize) < 0 ? 0 : (row - ksize);for (int col = 0; col < w + radius; col++) {x2 = (col + 1) > w ? w : (col + 1);x1 = (col - ksize) < 0 ? 0 : (col - ksize);cx = (col - radius) < 0 ? 0 : col - radius;cy = (row - radius) < 0 ? 0 : row - radius;int num = (x2 - x1)*(y2 - y1);for (int i = 0; i < ch; i++) {// 积分图查找和表,计算卷积int s1 = getblockSum(sum, x1, y1, cx, y2, i);int s2 = getblockSum(sum, cx, y1, x2, y2, i);result.at(cy, cx)[i] = saturate_cast(s2 - s1);}}}Mat dst, gray;convertScaleAbs(result, dst);normalize(dst, dst, 0, 255, NORM_MINMAX);cvtColor(dst, gray, COLOR_BGR2GRAY);imshow("edge_demo", gray);}int getblockSum(Mat &sum, int x1, int y1, int x2, int y2, int i) {int tl = sum.at(y1, x1)[i];int tr = sum.at(y2, x1)[i];int bl = sum.at(y1, x2)[i];int br = sum.at(y2, x2)[i];int s = (br - bl - tr + tl);return s;} 五、运行效果

 

 

免责声明:非本网注明原创的信息,皆为程序自动获取互联网,目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责;如此页面有侵犯到您的权益,请给站长发送邮件,并提供相关证明(版权证明、身份证正反面、侵权链接),站长将在收到邮件12小时内删除。

相关阅读

一周热门

查看更多