当前位置: 首页 > news >正文

桥南做网站上海网站快速优化排名

桥南做网站,上海网站快速优化排名,php网站开发怎么接私活,百家号自媒体平台注册背景 我需要对一张图像应用仿射变换,并确保变换后的图像内容不发生信息丢失。为此,需要根据变换后图像的四个角点,计算其最小外接矩形,并以此矩形为区域裁剪变换后的图像。目标是获得一个完整、有效保留原始图像信息的最小包围图…

背景

我需要对一张图像应用仿射变换,并确保变换后的图像内容不发生信息丢失。为此,需要根据变换后图像的四个角点,计算其最小外接矩形,并以此矩形为区域裁剪变换后的图像。目标是获得一个完整、有效保留原始图像信息的最小包围图像区域。

代码如下

int affineTransform(const std::string& srcImagePath,const std::string& dstImagePath,const Point* srcPoints,const Point* dstPoints,double* affineParams,int debugFlag
) {// 1. 加载原始图像cv::Mat srcImage = cv::imread(srcImagePath, cv::IMREAD_UNCHANGED);if (srcImage.empty()) {std::cerr << "Failed to load image: " << srcImagePath << std::endl;return -1;}// 2. 输入点校验if (!srcPoints || !dstPoints) return -2;constexpr int REQUIRED_POINTS = 3;std::vector<cv::Point2f> srcPts, dstPts;for (int i = 0; i < REQUIRED_POINTS; ++i) {srcPts.emplace_back(srcPoints[i].x, srcPoints[i].y);dstPts.emplace_back(dstPoints[i].x, dstPoints[i].y);}// 3. 获取仿射变换矩阵并提取参数cv::Mat affineMat = cv::getAffineTransform(srcPts, dstPts);extractAffineParameters(affineMat, affineParams);// 4. 原图四角及变换后的边界框std::vector<cv::Point2f> corners = {{0, 0},{static_cast<float>(srcImage.cols), 0},{static_cast<float>(srcImage.cols), static_cast<float>(srcImage.rows)},{0, static_cast<float>(srcImage.rows)}};std::vector<cv::Point2f> transformedCorners;cv::transform(corners, transformedCorners, affineMat);cv::Rect boundingBox = cv::boundingRect(transformedCorners);// 5. 计算需要填充的边界int padLeft = boundingBox.x < 0 ? -boundingBox.x : 0;int padTop  = boundingBox.y < 0 ? -boundingBox.y : 0;// 6. 根据通道数设置白色边界cv::Scalar borderColor;switch (srcImage.channels()) {case 1: borderColor = cv::Scalar(255); break;case 3: borderColor = cv::Scalar(255, 255, 255); break;case 4: borderColor = cv::Scalar(255, 255, 255, 255); break;default: throw std::runtime_error("Unsupported number of channels.");}// 7. 执行图像扩展cv::Mat paddedImage;cv::copyMakeBorder(srcImage, paddedImage, padTop, 0, padLeft, 0, cv::BORDER_CONSTANT, borderColor);// 8. 更新坐标后重新计算变换矩阵cv::Point2f offset(padLeft, padTop);for (auto& pt : srcPts) pt += offset;for (auto& pt : dstPts) pt += offset;cv::Mat adjustedAffineMat = cv::getAffineTransform(srcPts, dstPts);// 9. 仿射变换到目标图像cv::Size dstSize(boundingBox.width + padLeft, boundingBox.height + padTop);cv::Mat dstImage;cv::warpAffine(paddedImage, dstImage, adjustedAffineMat, dstSize, cv::INTER_LINEAR, cv::BORDER_CONSTANT, borderColor);// 10. 如果变换后图像偏移,进行裁剪if (boundingBox.x > 0 || boundingBox.y > 0) {boundingBox.x = std::max(boundingBox.x,0);boundingBox.y = std::max(boundingBox.y,0);int cropX = std::min(boundingBox.x, dstImage.cols);int cropY = std::min(boundingBox.y, dstImage.rows);int cropWidth  = std::max(0, dstImage.cols - cropX);int cropHeight = std::max(0, dstImage.rows - cropY);cv::Rect validRoi(cropX, cropY, cropWidth, cropHeight);dstImage = dstImage(validRoi).clone();}// 11. 调试信息if (debugFlag) {std::cout << "[AffineTransform Debug Info]\n";std::cout << "Original Corners: "; printPoints(corners);std::cout << "Transformed Corners: "; printPoints(transformedCorners);std::cout << "Bounding Box: x=" << boundingBox.x << ", y=" << boundingBox.y<< ", w=" << boundingBox.width << ", h=" << boundingBox.height << "\n";std::cout << "Padding: left=" << padLeft << ", top=" << padTop << "\n";std::cout << "Affine Matrix:\n" << affineMat << "\n";std::cout << "Adjusted Affine Matrix:\n" << adjustedAffineMat << "\n";std::cout << "Output Size: " << dstImage.cols << " x " << dstImage.rows << "\n";}// 12. 保存图像return cv::imwrite(dstImagePath, dstImage) ? 0 : -3;
}

解释

随便在网上找一下放射变换的教程,可以知道,变换后的图像,经常是缩小且周围白边很大。因为一不小心就会过界导致图像信息丢失。一般的教程也不处理最小外接矩形。
思路如下:
首先是将原图的四个角进行放射变换。由变换后的四个角得到最小包围盒:cv::Rect boundingBox = cv::boundingRect(transformedCorners);

如果boundingBox 左上角顶点有负数,则说明变换后的图像到了第234象限,我们需要向上,向左扩展图像。这是第七步做的事情。得到扩充后的图像

将图像扩充白边以后,我们原图的坐标系其实被改变了,即向左上方移动了。所以我们要把原来计算仿射变换矩阵的三个点平移,重新计算仿射变换。

我们使用扩充后的图像和第二次计算的放射变换进行变换。得到目标图像。

第十步,如果变换后的图像包围盒的左上点并不是原点,我们还要进行剪裁

如此,才能得到最小矩形包围的图像

http://www.dtcms.com/a/475883.html

相关文章:

  • 为什么要学电商网站建设用什么网站做一手房最好
  • 邢台哪里建网站网站建设的建议
  • 百度网站流量统计怎样做一个网站赚钱吗
  • Spring轻量级文件预览的组件
  • 网站建设与管理课程实训杭州西湖区抖音seo哪里找
  • 做团购网站商品从哪里找做内容的网站
  • 有哪些好的ps素材网站做爰全过程免费网站可以看
  • 网站自助制作公司网站设计要求
  • 苏州市吴江区住房和城乡建设局网站网站建设与网页设计 视频
  • 东莞官方网站 优帮云有实力的网站建设公司
  • 装饰公司手机网站云海建设工程有限公司网站
  • 如何建学校网站wordpress云建站教程
  • 在网站上做远程教育系统多少钱wordpress置顶精华图标
  • 怎么给网站备案网站制作开票几个点
  • 产品发布网站自己制作上传图片的网站怎么做
  • 龙岩做网站哪家最好专做蔬菜大棚的网站
  • 网站开发+语音泽库县公司网站建设
  • Ultralytics代码库深度解读【二】: TensorRT 引擎文件的构建与序列化
  • 广东网站建设哪家中国外贸网站
  • 做个卖东西的网站myeclipse做网站
  • 学生做网站的工作室网站建设有哪些荣誉
  • 字画价格网站建设方案无锡大型网站建设
  • 什么网站做家具出口做网络营销推广的公司
  • 外包网站怎么做seo响应式网站不加载图片
  • 河北建设网站公司wordpress postgre
  • 青岛网站建设青岛新思维做dapp开发广州
  • 【前缀和】| LeetCode 974题解 和可被K整除的子数组
  • 阿克苏建设租房信息阿克苏租房网站网站改版思路
  • 电商网站开发框架网站推广怎么做
  • 微信网站建设报价单应用商店软件