如何在二维图像中的不规则形状上应用纹理?

2023-12-27

我正在尝试从 UIColor 图案图像在 CALayer 上应用纹理。纹理正在应用,但未正确透视转换。看起来我的绘图逻辑存在问题,即我需要使用纹理图像并将其映射到不规则形状。我做了一些研究,发现这件事可以通过 OpenGL 或 Metal 通过将纹理图像映射到 2D 图像中的不规则形状来实现。

寻找某种指导,如何正确透视变换瓷砖图案?

        let image = UIImage(named: "roofTiles_square")?.flattened
        
        if let realImage = image {
            let color = UIColor(patternImage: realImage)
            controller.quadView.quadLayer.fillColor = color.cgColor
        }

任何帮助将非常感激。

Thanks


我正在编写详细的解决方案,但我想确保我正在解决正确的问题。计划是创建一个转换,正确扭曲“屋顶瓦片”图案(或任何此类图案)的版本,以便在映射到右侧图像中的四边形时正确地透视扭曲?即,四边形 ABCE 映射到四边形 A'B'C'E'?

第一步是计算单应性 https://mattmaulion.medium.com/homography-transform-image-processing-eddbcb8e4ff7将四边形 ABCD 映射到四边形 A'B'C'D'。OpenCV为此提供了方法 https://docs.opencv.org/master/d9/dab/tutorial_homography.html,但是让我们自己做一下数学计算。我们正在搜索一个 3x3 矩阵 H,将点 A、B、C、D 映射到点 A'、B'、C'、D',如下所示(我们实际上会以相反的方式进行操作):

使用 3D 同质向量 (x,y,w) 允许我们在 3D 中工作,除以 w 提供了必要的透视缩短(长话短说)。 事实证明,H 的任何比例倍数都有效,这意味着它只有 8 个自由度(而不是完整的 3*3 = 9)。这意味着我们想要 HA'A因此它们的叉积为零:

如果我们执行叉积,我们可以将最后一个方程重写为

上面的最后一个方程实际上是前两个方程的线性组合(将第一个方程乘以 x,将第二个方程乘以 y,将它们相加,得到第三个方程)。由于第三个方程是线性相关的,我们将其丢弃并仅使用前两个方程。对第二个方程求反,交换它们,然后将它们转换为矩阵形式,我们得到

因此一点对应A' - A产生两个方程。 如果我们有 n 个点对应,我们会得到 2n 个方程:

我们需要 n >= 4 才能有至少 8 个方程才能得到正确的解;即,我们至少需要 4 个(非共线)点。 因此我们有一个齐次方程组 我们解决使用奇异值分解 https://en.wikipedia.org/wiki/Singular_value_decomposition:

显然,简单的解决方案 h = 0 有效,但不是很有用。 将 h 设置为 V 的最后一列会得到最小二乘 我们系统的误差解,其中 h 具有单位长度。

让我们为您的具体示例计算 H。我们假设来源 要变换的图像为 WxH = 500x300,因此 A = (0,0)、B = (W,0)、C = (0,H) 和 D = (W,H)。目标图像是 484x217,我找到了 屋顶的角点为 A' = (70.7, 41.3), B' = (278.8, 76.3), C' = (136.4, 121,2),D' = (345.1, 153,2)。我会用Eigen https://eigen.tuxfamily.org/index.php?title=Main_Page到 进行计算。所以我将加载我的源和目的地 将点转化为矩阵:

#include <Eigen/Dense>
...
constexpr double W = 500;
constexpr double H = 300;
constexpr size_t N = 4;

Eigen::Matrix<double,2,N> SRC;
SRC <<
    0, W, 0, W,
    0, 0, H, H;
Eigen::Matrix<double,2,N> DST;
DST <<
    70.7, 278.8, 136.4, 345.1,
    41.3,  76.3, 121.2, 153.2;

我如上所述构造 8x9 矩阵 A

Eigen::Matrix<double,2*N,9> A;
A.setZero();
for (size_t i = 0; i < N; i++) {
    const double x_ = DST(0,i), y_ = DST(1,i);
    const double x  = SRC(0,i), y  = SRC(1,i);
    A(2*i,0) = A(2*i+1,3) = x_;
    A(2*i,1) = A(2*i+1,4) = y_;
    A(2*i,2) = A(2*i+1,5) = 1;
    A(2*i,6) = -x*x_;
    A(2*i,7) = -x*y_;
    A(2*i,8) = -x;
    A(2*i+1,6) = -y*x_;
    A(2*i+1,7) = -y*y_;
    A(2*i+1,8) = -y;
}

然后我计算 SVD,从 V 的最后一列,并将结果存储在 3x3 矩阵中:

Eigen::JacobiSVD<Eigen::Matrix<double,2*N,9>> svd(A, Eigen::ComputeFullV);
Eigen::Matrix<double,9,1> h = svd.matrixV().col(8);
Eigen::Matrix3d Homography;
Homography <<
    h(0), h(1), h(2),
    h(3), h(4), h(5),
    h(6), h(7), h(8);

产生所需的 3x3 矩阵 H:

  -0.016329     0.013427      0.599927
   0.004571    -0.0271779     0.799277
   1.78122e-06 -2.83812e-06  -0.00613631

我们可以使用 OpenCV 查看扭曲图像示例。 我加载源纹理和单应性 H 并使用 OpenCVwarpPerspective功能 https://docs.opencv.org/master/da/d54/group__imgproc__transform.html#gaf73673a7e8e18ec6963e3774e6a94b87

#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>

int main() {
    cv::Mat sourceImage = imread("texture.png", cv::IMREAD_COLOR);
    cv::Matx33d H(-0.016329, 0.013427, 0.599927,
                  0.004571, -0.0271779, 0.799277,
                  1.78122e-06, -2.83812e-06, -0.00613631);
    cv::Mat destImage;
    cv::warpPerspective(sourceImage, destImage, H, cv::Size(487,217),
                        cv::INTER_LINEAR | cv::WARP_INVERSE_MAP);
    cv::imwrite("warped.png", destImage);
    return 0;
}

结果看起来似乎合理:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在二维图像中的不规则形状上应用纹理? 的相关文章

  • SwiftUI 检测用户何时截取屏幕截图或屏幕录制

    On UIViewController我们可以轻松地将观察者添加到控制器 喜欢 class ViewController UIViewController override func viewDidLoad super viewDidLoa
  • iOS SecItemCopyMatching RSA 公钥格式?

    我正在尝试从已生成的密钥对 两个SecKeyRefs 以便通过线路发送 我所需要的只是一个简单的 modulus exponent 对 它应该正好占用 131 个字节 模数为 128 指数为 3 但是 当我获取关键信息时NSData对象 我
  • sizeToFit 运行异常

    我有一段代码 每次发生后端数据库更改时都会执行 本质上我在父视图中有一个标签 标签由许多状态消息之一更新 每个状态消息位于不同的行上 并以换行符 n 结尾 每条状态消息只能在一行上 并且不能过多 我遇到的问题是 当视图首次重新加载时 一切正
  • iOS 中系统日期更改后如何更改带有日期的标签?

    我有一个简单的查询 但不知道该怎么做 这就是我想要实现的目标 1 我有一个带有今天日期的 UILabel 即 29 04 12 2 在午夜 我希望该标签自行更新为 30 04 12 而无需更改视图或按任何内容 这是第2步 我不知道该怎么做
  • 在 UITableViewCell 内动态更改标签宽度

    我正在尝试建立一个自定义表格视图 正如您在图片中看到的 我在故事板一侧将标签的宽度默认设置为 160 磅 并在加载表格时动态更改宽度 我通过修改 cellForRowAtIndexPath 委托方法来实现此目的 因此 根据日期的长度 我设置
  • iOS - 在 UITabBar 上方获取所需的阴影

    我试图让我的标签栏阴影看起来像这张图片中看到的那样 这样做的最佳方法是什么 我正在使用 Objective C Thanks 您可以使用以下代码为任何 UI 对象提供阴影 tabBar layer shadowOffset CGSize w
  • Objective C 宏附加到字符串

    我认为这是一件非常简单的事情 但由于我是 iOS 开发和 Objective C 的新手 所以我无法弄清楚 define RESTFUL PATH PREFIX https gogch com gch restful define LOGI
  • iOS5 和 Facebook API

    我想将我的应用程序与 Facebook 集成并从 github 下载 Facebook ios sdk 但是 该 sdk 适用于 Xcode 4 0 代码库 我正在使用 Xcode 4 2 for iOS 5 beta 5 应用程序 是否有
  • 如何在 iPad 应用程序上禁用横向方向?

    我创建了一个全新的单视图 iOS 通用 Swift 应用程序 然后 我在应用程序设置中取消选中 横向左 和 横向右 我在 iPhone 上运行了它 万岁 无论我如何旋转手机 它都会保持纵向模式 然后我在 iPad 上运行它 它会旋转到任何内
  • 在后台运行 URL 请求

    我想在一定的时间间隔内发出 url 请求 例如 每 10 分钟应用程序应该发出一次 url 调用并获取一些 json 数据 应用程序在后台运行时应该能够执行此操作 这可以做到吗 如果是这样 这是否违反 Apple 服务条款 有什么限制吗 i
  • 移动设备上的 TensorFlow(Android、iOS、Windows Phone)

    我目前正在寻找不同的深度学习框架 特别是用于训练和部署卷积神经网络 要求是 它可以在带有 GPU 的普通 PC 上进行训练 但训练后的模型必须部署在三个主要的移动操作系统上 即 Android iOS 和 Windows Phone Ten
  • 在后台继续下载

    我正在创建一个应用程序 其中我从服务器下载一些数据 在后台运行时 我希望连接继续运行 以便可以下载数据 我知道有方法应用程序委托 void applicationDidEnterBackground UIApplication applic
  • 在 Swift 中,如何为具有自动布局的 UIView 制作动画,就像页面滑入一样?

    我尝试创建一个 UIView 来表示一个大小与设备屏幕相同的页面 由于该应用程序支持方向 因此我使用 AutoLayout 来构建它 它工作正常 直到我尝试将页面动画化以从右侧滑入 经过一番研究后 我能想到的最好的办法是 myView UI
  • Swift 错误:发出 SIGABRT 信号如何解决

    我只是 Swift 编码的初学者 我的想法很简单 就是一个有两个按钮的应用程序 单击时 文本字段将更改其文本 在 Main StoryBoard 中 我添加一个文本字段和两个按钮 在 ViewController swift 文件中 我这样
  • dyld:无法加载插入的库,但可以在模拟器和另一部 iPhone 上使用

    所以我在过去的几个小时里在我的应用程序上编码 在某个时候我决定在我的 iPhone 8 13 3 1 上启动我的应用程序而不是使用模拟器 13 3 它立即崩溃并出现以下错误 dyld warning could not load inser
  • 如何将NSTextView的格式化内容转换为字符串

    我需要将 NSTextView 的内容从 Mac 应用程序传输到 iOS 应用程序 我使用 XML 作为传输文件格式 所以我需要将 NSTextView 的内容 文本 字体 颜色等 保存为字符串 有什么办法可以做到这一点吗 一种方法是存档
  • 共享扩展程序未出现在能够在 iPhone 上共享照片的应用程序列表中

    我正在尝试创建一个共享应用程序扩展 并按照以下来源的教程进行操作 http www technetexperts com mobile share extension in ios application overview with exa
  • 如何删除以前的 ViewController

    我是一名学生 对编程还很陌生 我正在尝试在业余时间学习 Objective C Swift 我使用 spriteKit 和 swift 制作了一个游戏 有多个菜单 场景 我正在尝试从一个视图控制器转换到另一个视图控制器 为此 我使用了以下代
  • 构建 iOS 应用程序后退出代码 1 错误

    我正在尝试使用 RestKit 构建我的项目 当我构建它时 我收到以下错误 我尝试使用 Apple LLVM 3 0 和 LLVM GCC 4 2 进行编译 两者都产生相同的结果 任何人有任何想法是什么导致了这个问题 Ld Users Ji
  • Swift:UICollectionViewCell didSelectItemAtIndexPath 更改背景颜色

    我可以轻松更改单元格的背景颜色CellForItemAtIndexPath method func collectionView collectionView UICollectionView cellForItemAtIndexPath

随机推荐

  • Laravel 5.6 存储链接已存在,但尝试从公共文件夹获取文件时出现 404 错误

    我使用以下命令创建了一个符号链接 php artisan storage link 然后我创建了一个文件storage app public 根据文档 我可以通过以下方式获取该文件的链接 asset storage file txt htm
  • 如何使用lxml创建文本节点?

    我使用 lxml 和 python 来操作 xml 文件 我想创建一个最好没有标签的文本节点 而不是创建一个新的Element然后向其附加文本 我怎样才能做到这一点 我可以在中找到与此等效的内容xml dom minidompython 的
  • Proguard 和 R8 有什么区别?

    新版本的 Android Studio 3 4 刚刚发布 默认支持 R8 而不是 Proguard 有人可以解释一下两者之间的主要区别以及使用 R8 的任何明显好处吗 Android 构建过程的历史不断变化 开发人员不断尝试使其在构建时间和
  • 如何强制 iOS 立即更改背景颜色?

    有什么方法可以立即更改窗口的背景颜色吗 我需要一个闪烁的背景 即红 绿以一秒的间隔闪烁 正如我所见 背景颜色不会立即改变 而是仅在功能保留时才改变 有没有办法强制系统立即更改它并重绘窗口背景 void viewDidLoad super v
  • @将较少文件导入到有限范围内

    我想从另一个 less 文件导入所有样式 但范围有限 我正在尝试这个 我的网站 less wrapper class import path to styles less 但这根本不起作用 我使用基于浏览器的 less js 选项 并且可以
  • php 全局修剪 $_post

    你能修剪所有 POST 变量吗 因为我现在有一个很长的清单来修剪每个变量 看起来很不专业 我认为修剪 POST 也许会起作用 但没有 你可以这样做array map http php net array map POST array map
  • 如何修复 Android Studio 中的 VectorDrawableCompat 配置错误?

    我在 Android studio 中创建了一个项目 即使不修改项目中的任何单个字符 我也无法运行它 它给出以下错误 java lang RuntimeException 无法启动活动 组件信息 com kk myapplication c
  • 交集完成后,数组中的顺序是否保留?

    当我对两个数组进行交集时 是否可以保证结果顺序基于第一个数组的顺序 例如 如果我有 a 1 2 3 b 3 2 1 could a b return 3 2 1 代替 1 2 3 这是我所期望的 我在 RDoc 或 Pickaxe 的 Ar
  • 如何以编程方式调用 maven-resources-plugin

    我正在编写一个自定义 Maven 插件 该插件的部分工作是过滤复制一些资源 我写的代码如下所示 CopyResourcesMojo rm new CopyResourcesMojo rm setOutputDirectory outputD
  • 如何查找 Linux 上 Java Desktop API 需要哪些库?

    我正在尝试找到一种方法来确定 Java 需要哪些库才能使 Desktop API 工作 特别是BROWSE功能 我读了一些指南 错误报告和解决方法 但它们都不起作用 我可以通过安装使其在 Debian 上运行libgnome2 0 and
  • 将 C++ LPCWSTR 打印到文件

    我正在尝试将 LPCWSTR 值打印到文件中 但它只打印地址 而不打印值 我尝试过取消引用变量 使用 来获取 value 但这也不起作用 如何打印该值 void dump LPCWSTR text ofstream myfile C myf
  • 用于自定义图例的 Angular ngx-charts 选项?

    我目前正在使用 Angular2 的 ngx charts 我想自定义一些图例 例如将图例放在图表下方 或重命名图例字段 或使图例更宽 部分文本被截断 等 有什么好的选项来自定义图例吗 或者这通常是不可能的 或者最好的方法是什么 目前 我的
  • 添加 FFmpegMediaMetadataRetriever 后 Apk 大小增加

    我将依赖项 com github wseemann FFmpegMediaMetadataRetriever 1 0 3 添加到我的Android Studio中的应用程序 build gradle 中 apk从2 MB跳到16 MB 我只
  • 嘿,如何从 laravel 中的 klaviyo php-sdk 收集 laravel 中的短信同意

    嘿伙计们 有谁知道如何在 klaviyo 中添加短信内容吗 laravel 中的这个包 https github com klaviyo php klaviyo or just add a property to someone 基本上 我
  • 什么时候应该在 Material-UI 中使用 Typography?

    我正在使用 Material UI 但我有点困惑 有这个组件Typography https material ui com components typography typography但我真的不明白何时使用它以及它的目的是什么 什么时
  • 禁用 ScrollView 中包含的 ListView 的滚动

    我想为我的用户显示个人资料屏幕 它必须具有三个视图 2Buttons and a ImageView and a ListView显示该用户制作的内容 但是 我不想要ListView滚动 相反 我希望它尽可能大 并将我所有的观点放在一个Sc
  • 大写 utf8 字符与其小写变体的字节数始终相同吗?

    显然对于拉丁字母来说也是如此 但我是从概念意义上跨语言和 Unicode 规范来问这个问题的 实际上 这是为了比较两个字符串而出现的 如果您已经知道它们在所有语言中的字节数不同 您是否可以认为足以保证它们不是同一字符串的不同 大小写 版本
  • Android IME,在EditText中设置光标位置

    我正在使用软键盘 需要在 IME 编辑文本中设置光标位置 如上图所示 我创建了软键盘 我们可以看到在编辑文本和当前光标位置 由蓝色指示器显示 中输入了一些文本 我需要将光标位置设置在当前行的末尾 在我们的例子中 在图像中首先以红色显示的行的
  • 如何在 Ruby 应用程序中找到未使用的方法?

    我有一个 Ruby 应用程序 其中有很多类 模块 其中一些未使用 有没有一种简单的方法可以找出哪个 我正在考虑做一个配置文件 然后使用它的输出 还有其他想法吗 像 rcov 这样的覆盖工具可能会有所帮助 https github com r
  • 如何在二维图像中的不规则形状上应用纹理?

    我正在尝试从 UIColor 图案图像在 CALayer 上应用纹理 纹理正在应用 但未正确透视转换 看起来我的绘图逻辑存在问题 即我需要使用纹理图像并将其映射到不规则形状 我做了一些研究 发现这件事可以通过 OpenGL 或 Metal