OpenCV运动分析和目标跟踪(1)累积操作函数accumulate()的使用
- 操作系统:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 编程语言:C++11
算法描述
将一个图像添加到累积图像中。
该函数将 src 或其部分元素添加到 dst 中:
dst
(
x
,
y
)
←
dst
(
x
,
y
)
+
src
(
x
,
y
)
if
mask
(
x
,
y
)
≠
0
\texttt{dst} (x,y) \leftarrow \texttt{dst} (x,y) + \texttt{src} (x,y) \quad \text{if} \quad \texttt{mask} (x,y) \ne 0
dst(x,y)←dst(x,y)+src(x,y)ifmask(x,y)=0
该函数支持多通道图像。每个通道独立处理。
cv::accumulate 函数可以用于收集由静止相机拍摄的场景背景的统计数据,并用于进一步的前景-背景分割。
函数原型
void cv::accumulate
(
InputArray src,
InputOutputArray dst,
InputArray mask = noArray()
)
参数
-
参数src 输入图像,类型为 CV_8UC(n),CV_16UC(n),CV_32FC(n) 或 CV_64FC(n),其中 n 是一个正整数。
-
参数dst 累积图像,与输入图像具有相同数量的通道,并且深度为 CV_32F 或 CV_64F。
-
参数mask 可选的操作掩码。
代码示例
#include <iostream>
#include <opencv2/opencv.hpp>
int main()
{
// 加载一个真实的图像
cv::Mat sourceImage = cv::imread( "/media/dingxin/data/study/OpenCV/sources/images/sun2.jpg", cv::IMREAD_COLOR );
if ( sourceImage.empty() )
{
std::cout << "Error loading image" << std::endl;
return -1;
}
// 获取源图像的尺寸和通道数
cv::Size imageSize = sourceImage.size();
int numChannels = sourceImage.channels();
// 输出源图像的尺寸和类型
std::cout << "Source Image Size: " << imageSize << std::endl;
std::cout << "Source Image Type: " << sourceImage.type() << std::endl;
std::cout << "Source Image Channels: " << numChannels << std::endl;
// 创建一个空的累积图像
cv::Mat cumulativeImage = cv::Mat::zeros(imageSize, CV_32FC(numChannels)); // 累积图像类型为 CV_32FC3
// 输出累积图像的尺寸和类型
std::cout << "Cumulative Image Size: " << cumulativeImage.size() << std::endl;
std::cout << "Cumulative Image Type: " << cumulativeImage.type() << std::endl;
std::cout << "Cumulative Image Channels: " << cumulativeImage.channels() << std::endl;
// 将源图像转换为浮点类型
cv::Mat sourceImageFloat;
sourceImage.convertTo(sourceImageFloat, CV_32FC(numChannels), 1.0 / 255.0);
// 输出转换后的图像尺寸和类型
std::cout << "Converted Image Size: " << sourceImageFloat.size() << std::endl;
std::cout << "Converted Image Type: " << sourceImageFloat.type() << std::endl;
std::cout << "Converted Image Channels: " << sourceImageFloat.channels() << std::endl;
// 创建一个掩码图像
cv::Mat mask = cv::Mat::ones(imageSize, CV_8U) * 255; // 全部像素为255,即不使用掩码
// 输出掩码图像的尺寸和类型
std::cout << "Mask Image Size: " << mask.size() << std::endl;
std::cout << "Mask Image Type: " << mask.type() << std::endl;
// 确保累积图像和源图像的尺寸一致
if (cumulativeImage.rows != sourceImageFloat.rows || cumulativeImage.cols != sourceImageFloat.cols) {
std::cout << "Error: Cumulative image and source image do not have the same size." << std::endl;
return -1;
}
// 确保累积图像和源图像的通道数一致
if (cumulativeImage.channels() != sourceImageFloat.channels()) {
std::cout << "Error: Cumulative image and source image do not have the same number of channels." << std::endl;
return -1;
}
// 累积源图像到累积图像中
int numAccumulations = 100; // 增加累加次数
for (int i = 0; i < numAccumulations; ++i) {
cv::accumulate(sourceImageFloat, cumulativeImage, mask);
}
// 显示累积图像
cv::Mat normalizedCumulativeImage;
cv::normalize(cumulativeImage, normalizedCumulativeImage, 0, 255, cv::NORM_MINMAX, CV_8U);
// 使用高对比度的色彩映射
cv::Mat enhancedCumulativeImage;
cv::applyColorMap(normalizedCumulativeImage, enhancedCumulativeImage, cv::COLORMAP_JET);
cv::imshow("Original Image", sourceImage);
cv::imshow("Cumulative Image", enhancedCumulativeImage);
cv::waitKey( 0 );
return 0;
}