文章目录
-
- 一、SATD是什么
- [二、 技术细节](#二、 技术细节)
- [1.matlab 连续读取图片,并截取区域](#1.matlab 连续读取图片,并截取区域)
- [2.matlab SATD相似度识别](#2.matlab SATD相似度识别)
- [3.matlab 在多维矩阵中找最小值](#3.matlab 在多维矩阵中找最小值)
- [三、c++ 实现SATD](#三、c++ 实现SATD)
-
- [3.1 OpenCV和C++实现SATD](#3.1 OpenCV和C++实现SATD)
- [3.2 c++ opencv](#3.2 c++ opencv)
- 小结
一、SATD是什么
提示:这里可以添加技术名词解释
SATD(Sum of Absolute Transformed Differences)是一种用于图像匹配的算法,其原理主要包含以下步骤:
- 将模板图像与待匹配图像做差,得到一个差值矩阵Q。
- 对差值矩阵Q进行Hadamard变换(一种特殊的矩阵变换)。Hadamard变换等价于把原图像Q矩阵左右分别乘以一个Hadamard变换矩阵H。Hadamard变换矩阵H的元素都是1或-1,是一个正交矩阵,可以由MATLAB中的hadamard(n)函数生成,n代表n阶方阵。
- 对变换后的矩阵求其元素的绝对值之和,得到一个SATD值。这个SATD值作为相似度的判别依据。
- 对所有待匹配的子图都进行如上的变换后,找到SATD值最小的子图,便是最佳匹配。
以上信息仅供参考,如需更多信息,建议查阅图像处理相关的书籍或咨询图像处理专家。
二、 技术细节
1.matlab 连续读取图片,并截取区域
为了连续读取1到1000张图片,并截取中间的100*100区域,然后重新存储为M1到M1000,你可以使用以下的MATLAB代码:
matlab
% 设定图片文件夹路径
folderPath = 'path_to_your_image_folder'; % 请替换为你的图片文件夹路径
% 遍历每张图片
for i = 1:1000
% 生成当前图片的文件名
fileName = fullfile(folderPath, sprintf('I%d.jpg', i)); % 假设原始图片命名为I1.jpg, I2.jpg, ... I1000.jpg
% 读取图片
img = imread(fileName);
% 检查图片是否读取成功
if isempty(img)
error(sprintf('无法读取图片: %s', fileName));
end
% 计算截取区域
[height, width, ~] = size(img);
xStart = max(1, width/2 - 50); % 100*100区域的左起点
yStart = max(1, height/2 - 50); % 100*100区域的上起点
cropImg = img(yStart:yStart+99, xStart:xStart+99, :);
% 存储截取后的图片
outputFileName = fullfile(folderPath, sprintf('M%d.jpg', i));
imwrite(cropImg, outputFileName);
end
注意事项:
- 请确保你的图片是
.jpg
格式。如果不是,请在代码中修改对应的扩展名。 - 这个代码假设原始图片的命名是连续的,从
I1.jpg
到I1000.jpg
。如果实际命名与此不符,请相应地调整文件名生成部分。 - 这个代码会截取图片中心附近的100*100区域。如果原始图片的尺寸小于这个区域,代码会自动调整截取区域以确保不会超出图片边界。
2.matlab SATD相似度识别
matlab
close all
clear all
clc
% src=double(rgb2gray(imread('baby.jpg'))); %长宽相等的
% mask=double(rgb2gray(imread('模板图像_bdd.jpg'))); %长宽相等的
src=double(rgb2gray(imread('frame_1442.jpg'))); %长宽相等的
mask=double(rgb2gray(imread('frame_1442_mask.jpg'))); %长宽相等的
[M,K]=size(src); %搜索图大小
N=size(mask,1); %模板大小
%%
hdm_matrix=hadamard(N); %hadamard变换矩阵
hdm=zeros(M-N+1,K-N+1); %保存SATD值
for i=1:M-N+1
for j=1:K-N+1
temp=(src(i:i+N-1,j:j+N-1)-mask)/256;
sw=(hdm_matrix*temp*hdm_matrix)/256;
hdm(i,j)=sum(sum(abs(sw)));
end
end
min_hdm=min(min(hdm));
[x, y]=find(hdm==min_hdm);
figure, imshow(uint8(mask));
title('模板图像');
imwrite(uint8(mask),'模板图像_zhuti_gray.jpg');
figure, imshow(uint8(src));
hold on;
rectangle('position',[y,x,N-1,N-1],'edgecolor','r');
title('STAD匹配结果');
hold off;
3.matlab 在多维矩阵中找最小值
在MATLAB中,min(min(hdm))
的作用是从一个多维数组(比如矩阵)中找到最小值。
具体解释如下:
min(hdm)
:当hdm
是一个矩阵时,这个操作会返回每一列的最小值,结果是一个行向量。min( ... )
:外面的min
函数作用于之前得到的行向量,返回该行向量中的最小值。
所以,min_hdm = min(min(hdm));
的意思是找到 hdm
矩阵中的最小值,并将其赋值给 min_hdm
。
例如,如果 hdm
是以下矩阵:
matlab
hdm = [3, 7, 2;
8, 1, 6;
4, 5, 9];
那么 min(hdm)
会返回 [3, 1, 2]
(每列的最小值),然后 min(min(hdm))
会返回 1
,这是整个矩阵的最小值。
这段MATLAB代码是在寻找数组hdm
中与最小值min_hdm
相等的元素的索引。
具体解释如下:
hdm == min_hdm
:这部分会返回一个逻辑数组,其中值为true
的位置表示hdm
中与min_hdm
相等的元素。find(...)
:这个函数会返回逻辑数组中true
的位置的索引。所以,如果hdm == min_hdm
返回的是一个与hdm
相同大小的逻辑数组,那么find(...)
会返回所有与min_hdm
相等的元素的索引。[x, y] = ...
:这部分将返回两个向量。向量x
包含所有与min_hdm
相等的元素的行索引,而向量y
包含它们的列索引。
例如,如果:
matlab
hdm = [3, 7, 2;
8, 1, 6;
4, 5, 9];
min_hdm = 1;
那么 [x, y] = find(hdm == min_hdm)
将返回 x = [2], y = [2]
,表示在第二行第二列的位置上,hdm
的值是1。
三、c++ 实现SATD
3.1 OpenCV和C++实现SATD
下面是使用OpenCV和C++实现SATD(Sum of Absolute Transformed Differences)的一个简单示例。在这个例子中,我将假设你已经有了待匹配的模板图像(template_img
)和待匹配的源图像(source_img
)。
注意:这个代码只是一个基本的示例,可能需要根据你的具体需求进行修改和优化。
cpp
#include <opencv2/opencv.hpp>
#include <iostream>
// 计算SATD
double computeSATD(const cv::Mat &img1, const cv::Mat &img2) {
cv::Mat diff;
cv::absdiff(img1, img2, diff); // 计算绝对差值
cv::Mat gray;
cv::cvtColor(diff, gray, cv::COLOR_BGR2GRAY); // 转换为灰度图像
cv::Mat abs_diff_mat;
cv::convertScaleAbs(gray, abs_diff_mat); // 转换为绝对值
double sum = cv::sum(abs_diff_mat)[0]; // 计算总和
return sum;
}
int main() {
// 读取图像
cv::Mat template_img = cv::imread("template.png", cv::IMREAD_GRAYSCALE);
cv::Mat source_img = cv::imread("source.png", cv::IMREAD_GRAYSCALE);
if (template_img.empty() || source_img.empty()) {
std::cout << "无法加载图像" << std::endl;
return -1;
}
// 确保图像大小相同
if (template_img.size() != source_img.size()) {
std::cout << "图像大小不一致" << std::endl;
return -1;
}
// 计算SATD值
double satd = computeSATD(template_img, source_img);
std::cout << "SATD值: " << satd << std::endl;
return 0;
}
这个代码首先计算两个图像的绝对差值,然后将差值图像转换为灰度图像,再将其转换为绝对值。最后,它计算并返回所有像素的绝对值之和,这就是SATD值。注意,这个代码没有进行任何形式的模板匹配优化,例如使用滑动窗口或快速近似算法。对于大型图像或实时应用,你可能需要使用这些优化方法来提高性能。
3.2 c++ opencv
要使用C++和OpenCV实现SATD(Sum of Absolute Transformed Differences)图像匹配,你需要遵循以下步骤:
-
设置环境:
- 安装OpenCV库。你可以从OpenCV官网下载并按照说明进行安装。
- 创建一个C++项目,并配置OpenCV库。
-
读取图像:
- 使用OpenCV的
imread
函数读取模板图像和待匹配图像。
- 使用OpenCV的
-
预处理:
- 如果需要,对图像进行预处理,如灰度化、平滑等。
-
定义SATD函数:
- 编写一个函数来计算两个图像的SATD值。该函数将接收两个图像作为输入,并返回它们的SATD值。
-
滑动窗口匹配:
- 在待匹配图像上使用滑动窗口技术。对于每个窗口位置,计算模板图像与当前窗口的SATD值。
- 记录每个位置的SATD值。
-
找到最佳匹配:
- 找到SATD值最小的位置,这就是最佳匹配位置。
-
显示结果:
- 在待匹配图像上标出最佳匹配位置。
- 使用OpenCV的
imshow
函数显示结果图像。
-
保存/输出结果:
- 如果需要,保存匹配结果图像或输出相关信息。
-
代码示例 :
下面是一个简化的C++和OpenCV实现SATD图像匹配的代码示例:
cpp
#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
#include <cmath>
double computeSATD(const cv::Mat& templateImg, const cv::Mat& sourceRegion) {
cv::Mat absDiff;
cv::absdiff(templateImg, sourceRegion, absDiff); // 计算绝对差值
return cv::sum(absDiff)[0]; // 返回绝对值之和
}
cv::Point findMatch(const cv::Mat& templateImg, const cv::Mat& sourceImg) {
int minSATD = INT_MAX;
cv::Point bestLocation;
int templateHeight = templateImg.rows;
int templateWidth = templateImg.cols;
for (int i = 0; i < sourceImg.rows - templateHeight; ++i) {
for (int j = 0; j < sourceImg.cols - templateWidth; ++j) {
cv::Rect region(j, i, templateWidth, templateHeight);
double currentSATD = computeSATD(templateImg, sourceImg(region));
if (currentSATD < minSATD) {
minSATD = currentSATD;
bestLocation = cv::Point(j, i); // 更新最佳匹配位置
}
}
}
return bestLocation; // 返回最佳匹配位置
}
int main() {
cv::Mat templateImg = cv::imread("template.png", cv::IMREAD_GRAYSCALE); // 读取模板图像(灰度)
cv::Mat sourceImg = cv::imread("source.png", cv::IMREAD_GRAYSCALE); // 读取待匹配图像(灰度)
if (templateImg.empty() || sourceImg.empty()) {
std::cerr << "Error: Could not load images." << std::endl;
return -1;
}
cv::Point matchLocation = findMatch(templateImg, sourceImg); // 找到最佳匹配位置
// 在源图像上画出匹配位置(例如使用矩形)并显示结果...
return 0;
}
这个示例展示了如何使用C++和OpenCV来实现基本的SATD图像匹配。注意,对于实际应用,可能需要进一步的优化和调整以提高性能和准确性。
小结
提示:这里可以添加总结
例如:
提供先进的推理,复杂的指令,更多的创造力。