- ubuntu24.04LTS自带opencv4.5
- 代码实例
//opencv_example.cpp
#include <opencv2/opencv.hpp>
#include <iostream>
int main() {
// 读取图像
cv::Mat img = cv::imread("image.jpg", cv::IMREAD_COLOR);
if (img.empty()) {
std::cerr << "无法读取图像!" << std::endl;
return -1;
}
// 显示图像
cv::imshow("显示图像", img);
cv::waitKey(0); // 等待按键
return 0;
}
- 编译(
usr/include/opencv4
包含opencv2
目录,编译执行导入外面一层目录)
g++ opencv_example.cpp -o opencv_example `pkg-config --cflags --libs opencv4`
- 执行
opencv_example
link-use sift : https://stackoverflow.com/questions/22722772/how-to-use-sift-in-opencv
安装拓展包
- link: https://github.com/opencv/opencv_contrib.git
OpenCV Contrib 是 OpenCV 的一个附加模块库,包含了一些在核心 OpenCV 库中没有的额外功能和算法。它的主要作用和特点包括:
介绍
1. 扩展功能
OpenCV Contrib 提供了一些额外的计算机视觉和图像处理功能,这些功能可能不够成熟或不够通用,无法包含在核心 OpenCV 中。通过使用 Contrib 模块,用户可以访问这些实验性或特定领域的功能。
2. 额外的算法
Contrib 模块中包含了一些特定的算法和工具,例如:
- xfeatures2d:包含 SIFT、SURF 和其他特征检测和描述子提取算法。
- text:用于文本检测和识别的工具。
- tracking:包含多种目标跟踪算法。
- saliency:用于显著性检测的算法。
- face:人脸检测和识别的相关功能。
基础
致命陷阱: cv::Mat
- 只在创建Mat的时候,(row,col),其余(col,row)
- 如下,创建了一个3*row行,3*col列的图像
cv::Mat globalImage=cv::Mat::zeros(3*row, 3*col, CV_8UC3);
- 所有的向量位置,也是(col,row)的形式: 图像(row,col)的位置表示为(col,row);
ori_corners.push_back((cv::Mat_<double>(3,1) << col-1, 0,1));
- col代表x,row代表y
cv::Rect
cv::Rect(0, 0, img2.cols, img2.rows) 创建了一个从 (0, 0) 开始,宽度为 img2.cols,高度为 img2.rows 的矩形,通常表示整个图像 img2 的区域。
cv::vec4f
- 表示2D直线时,前两个表示方向,后两个表示端点;
操作
opencv如何把一个图像的某个菱形区域粘贴到另一个图像上?
在OpenCV中,可以通过以下步骤将一个图像的某个菱形区域粘贴到另一个图像上:
- 读取图像:使用
cv::imread
读取源图像和目标图像。 - 定义菱形区域:通过指定菱形的中心和大小,计算出菱形区域的四个顶点。
- 创建掩膜:使用掩膜来提取源图像中的菱形区域。
- 粘贴区域:将提取的菱形区域粘贴到目标图像的指定位置。
以下是一个示例代码,演示如何实现这一过程:
C++ 示例代码
#include <opencv2/opencv.hpp>
int main() {
// 读取源图像和目标图像
cv::Mat sourceImage = cv::imread("source_image.jpg");
cv::Mat targetImage = cv::imread("target_image.jpg");
// 检查图像是否成功读取
if (sourceImage.empty() || targetImage.empty()) {
std::cerr << "Could not open or find the images!" << std::endl;
return -1;
}
// 定义菱形区域的中心和大小
cv::Point center(100, 100); // 菱形中心
int width = 80; // 菱形的宽度
int height = 80; // 菱形的高度
// 计算菱形的四个顶点
std::vector<cv::Point> diamondPoints;
diamondPoints.push_back(cv::Point(center.x, center.y - height / 2)); // 上顶点
diamondPoints.push_back(cv::Point(center.x + width / 2, center.y)); // 右顶点
diamondPoints.push_back(cv::Point(center.x, center.y + height / 2)); // 下顶点
diamondPoints.push_back(cv::Point(center.x - width / 2, center.y)); // 左顶点
// 创建掩膜
cv::Mat mask = cv::Mat::zeros(sourceImage.size(), CV_8UC1);
cv::fillConvexPoly(mask, diamondPoints, cv::Scalar(255));
// 提取菱形区域
cv::Mat diamondRegion;
sourceImage.copyTo(diamondRegion, mask);
// 定义粘贴位置
cv::Point pasteLocation(50, 50); // 在目标图像上的粘贴位置
// 将菱形区域粘贴到目标图像上
for (int y = 0; y < diamondRegion.rows; y++) {
for (int x = 0; x < diamondRegion.cols; x++) {
if (mask.at<uchar>(y, x) > 0) { // 检查掩膜
targetImage.at<cv::Vec3b>(pasteLocation.y + y, pasteLocation.x + x) = diamondRegion.at<cv::Vec3b>(y, x);
}
}
}
// 显示结果
cv::imshow("Result", targetImage);
cv::waitKey(0);
return 0;
}
说明:
- 读取图像:使用
cv::imread
读取源图像和目标图像。 - 定义菱形区域:通过指定菱形的中心和大小,计算出菱形的四个顶点。
- 创建掩膜:使用
cv::fillConvexPoly
创建一个掩膜,填充菱形区域。 - 提取菱形区域:使用掩膜从源图像中提取菱形区域。
- 粘贴区域:将提取的菱形区域粘贴到目标图像的指定位置。
- 显示结果:使用
cv::imshow
显示结果图像。
注意事项:
- 确保粘贴位置在目标图像的有效范围内,以避免越界访问。
- 如果源图像和目标图像的大小不同,可能需要调整菱形区域的大小或粘贴位置。
simple multi-band blending
- link1: https://blog.csdn.net/m0_59023219/article/details/130733220
- link2:https://blog.csdn.net/qq_46396470/article/details/140087963
#include <opencv2/opencv.hpp>
#include <vector>
using namespace cv;
// 函数:创建拉普拉斯金字塔
std::vector<Mat> createLaplacianPyramid(const Mat& image, int levels) {
std::vector<Mat> pyramid;
Mat current = image.clone();
for (int i = 0; i < levels; i++) {
Mat down;
pyrDown(current, down);
Mat laplacian = current - downsample(down, current.size());
pyramid.push_back(laplacian);
current = down;
}
pyramid.push_back(current); // 最底层
return pyramid;
}
// 函数:重建图像
Mat reconstructFromPyramid(const std::vector<Mat>& pyramid) {
Mat current = pyramid.back();
for (int i = pyramid.size() - 2; i >= 0; i--) {
current = pyrUp(current) + pyramid[i]; // 使用 pyrUp 进行上采样
}
return current;
}
// 函数:多频带混合
Mat multiBandBlending(const Mat& img1, const Mat& img2, int levels) {
// 创建拉普拉斯金字塔
std::vector<Mat> laplacian1 = createLaplacianPyramid(img1, levels);
std::vector<Mat> laplacian2 = createLaplacianPyramid(img2, levels);
// 混合频带
std::vector<Mat> blendedPyramid;
for (size_t i = 0; i < laplacian1.size(); i++) {
Mat blended = (laplacian1[i] + laplacian2[i]) / 2; // 简单的平均混合
blendedPyramid.push_back(blended);
}
// 重建图像
return reconstructFromPyramid(blendedPyramid);
}
int main() {
// 读取图像
Mat img1 = imread("image1.jpg");
Mat img2 = imread("image2.jpg");
if (img1.empty() || img2.empty()) {
std::cerr << "无法读取图像!" << std::endl;
return -1;
}
// 确保图像大小相同
if (img1.size() != img2.size()) {
resize(img2, img2, img1.size());
}
// 进行多频带混合
Mat blended = multiBandBlending(img1, img2, 5);
// 显示结果
imshow("Blended Image", blended);
waitKey(0);
return 0;
}