双线性插值_亚像素边缘尺寸测量

2023-10-27

读了好几篇关于亚像素边缘的博客,记录几点收获总结,若有错,还请读者朋友指正。

  1. 亚像素边缘常见的方法主要是插值法和拟合法,如:近邻插值、双线性插值、三次插值、最小二乘法拟合等。
  2. 实际并不存在亚像素边缘坐标,可以通过放大或缩小图像获得原图像的亚像素位置在新图像中的展示。
  3. 尺寸测量时新图像的像素距离除以缩放比例即可获得原图像的亚像素精度的距离。

感谢博主萱子子子的插值代码。本文使用霍夫直线检测,简单通过直线尺寸测量进行了验证。

代码如下:

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

using namespace cv;
using namespace std;
Mat LinerInter(Mat &srcImage, double kx, double ky);

int main()
{
	Mat src = imread("D:/images/chazhi.jpg");
	Mat result = LinerInter(src,1.2,1.2);

	Mat srcImg, gray, binary;
	cvtColor(src, gray, COLOR_BGR2GRAY);
	threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
	Canny(binary, srcImg, 10, 200, 3);


	Mat gray_1, resultImg,binary_1;
	cvtColor(result, gray_1, COLOR_BGR2GRAY);
	threshold(gray_1, binary_1, 0, 255, THRESH_BINARY | THRESH_OTSU);
	Canny(binary_1, resultImg, 10, 200, 3);
	//直线距离
	vector<Vec4i> lines, lines_1;
	vector<float> dis, dis_1;
	HoughLinesP(srcImg, lines, 1, CV_PI / 180, 150, 30, 10);
	HoughLinesP(resultImg, lines_1, 1, CV_PI / 180, 150, 30, 10);
	//【7】迭代器遍历向量,line()函数绘制线段
	for (int i = 0; i < lines.size(); i++) {
		//插值前
		Point2i pt1(lines[i][0], lines[i][1]);
		Point2i pt2(lines[i][2], lines[i][3]);
		//cout << lines[i][0] << " " << lines[i][1] << " " << lines[i][2] << " " << lines[i][3] << endl;
		dis.push_back(sqrt(abs((pt1.x - pt2.x)) * abs((pt1.x - pt2.x)) + abs((pt1.y - pt2.y)) * abs((pt1.y - pt2.y))));
		line(src, pt1, pt2, Scalar(0, 0, 255), 1, LINE_AA);
	}
	//cout << lines_1.size() << endl;
	for (int i = 0; i < lines_1.size(); i++) {
		//插值后
		Point2i pt1_1(lines_1[i][0], lines_1[i][1]);
		Point2i pt2_1(lines_1[i][2], lines_1[i][3]);
		//cout << lines[i][0] << " " << lines[i][1] << " " << lines[i][2] << " " << lines[i][3] << endl;
		dis_1.push_back(sqrt(abs((pt1_1.x - pt2_1.x)) * abs((pt1_1.x - pt2_1.x)) + abs((pt1_1.y - pt2_1.y)) * abs((pt1_1.y - pt2_1.y))));
		line(result, pt1_1, pt2_1, Scalar(0, 0, 255), 1, LINE_AA);
	}
	for (int i = 0; i < dis.size(); i++) {
		cout << "dis = " << dis[i] << endl;
	}

	for (int i = 0; i < dis_1.size(); i++) {
		cout << "dis_1 = " << dis_1[i]/1.2 << endl;
	}

	imshow("src", srcImg);
	imshow("0.6, 1.2", resultImg);
	imshow("src", src);
	imshow("result", result);
	waitKey(0);
	return 0;
}

Mat LinerInter(Mat &srcImage, double kx, double ky)
{
	int rows = cvRound(srcImage.rows*kx);
	int cols = cvRound(srcImage.cols*ky);
	Mat resultImg(rows, cols, srcImage.type());
	int i, j;
	int xi;
	int yi;
	int x11;
	int y11;
	double xm;
	double ym;
	double dx;
	double dy;

	for (i = 0; i < rows; i++)
	{
		xm = i / kx;
		xi = (int)xm;
		x11 = xi + 1;
		dx = xm - xi;
		for (j = 0; j < cols; j++)
		{
			ym = j / ky;
			yi = (int)ym;
			y11 = yi + 1;
			dy = ym - yi;
			//判断边界
			if (x11 >(srcImage.rows - 1))
			{
				x11 = xi - 1;
			}
			if (y11 > (srcImage.cols - 1))
			{
				y11 = yi - 1;
			}
			//bgr
			resultImg.at<Vec3b>(i, j)[0] = (int)(srcImage.at<Vec3b>(xi, yi)[0] * (1 - dx)*(1 - dy)
				+ srcImage.at<Vec3b>(x11, yi)[0] * dx*(1 - dy)
				+ srcImage.at<Vec3b>(xi, y11)[0] * (1 - dx)*dy
				+ srcImage.at<Vec3b>(x11, y11)[0] * dx*dy);
			resultImg.at<Vec3b>(i, j)[1] = (int)(srcImage.at<Vec3b>(xi, yi)[1] * (1 - dx)*(1 - dy)
				+ srcImage.at<Vec3b>(x11, yi)[1] * dx*(1 - dy)
				+ srcImage.at<Vec3b>(xi, y11)[1] * (1 - dx)*dy
				+ srcImage.at<Vec3b>(x11, y11)[1] * dx*dy);
			resultImg.at<Vec3b>(i, j)[2] = (int)(srcImage.at<Vec3b>(xi, yi)[2] * (1 - dx)*(1 - dy)
				+ srcImage.at<Vec3b>(x11, yi)[2] * dx*(1 - dy)
				+ srcImage.at<Vec3b>(xi, y11)[2] * (1 - dx)*dy
				+ srcImage.at<Vec3b>(x11, y11)[2] * dx*dy);
		}

	}
	return resultImg;
}

结果:
在这里插入图片描述
不知道这个思路对不对,恳请斧正!
近邻插值:

# include<iostream>
# include<opencv2/highgui/highgui.hpp>

using namespace std;
using namespace cv;

Mat NearInter(Mat &srcImage, double kx, double ky)
{
	int rows = cvRound(srcImage.rows*kx);
	int cols = cvRound(srcImage.cols*ky);
	Mat resultImg(rows, cols, srcImage.type());
	int i, j, x, y;
	for (i = 0; i < rows; i++)
	{
		x = static_cast<int>((i + 1) / kx + 0.5) - 1;
		for (j = 0; j < cols; j++)
		{
			y = static_cast<int>((j + 1) / ky + 0.5) - 1;
			resultImg.at<Vec3b>(i, j) = srcImage.at<Vec3b>(x, y);
		}
	}
	return resultImg;
}

int main()
{
	Mat srcImg = imread("D:\\Visual Studio 2015\\lena.bmp");
	Mat resultImg = NearInter(srcImg, 0.6, 1.2);
	imshow("src", srcImg);
	imshow("0.6,1.2", resultImg);
	waitKey(0);
	return 0;
}

————————————————
原文链接:https://blog.csdn.net/xuan_zizizi/article/details/82747729

三次插值:

# include<iostream>
# include<cmath>
# include<opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;

float Bicubic(float x);
Mat ThreeInter(Mat &srcImage, double kx, double ky);

int main()
{
	Mat srcImg = imread("D:\\Visual Studio 2015\\lena.bmp");
	if (!srcImg.data)
	{
		cout << "图片不存在" << endl;
	}
	Mat resultImg = ThreeInter(srcImg, 0.6, 1.2);
	imshow("src", srcImg);
	imshow("0.6,1.2", resultImg);
	waitKey(0);
	return 0;
}


float Bicubic(float y)
{
	float x = abs(y);
	float a = -0.5;
	if (x <= 1.0)
	{
		return (a + 2)*pow(x, 3) - (a + 3)*pow(x, 2) + 1;
	}
	else if (x < 2.0)
	{
		return a*pow(x, 3) + 5 * a*pow(x, 2) - 4 * a;
	}
	else
	{
		return 0.0;
	}
}

Mat ThreeInter(Mat &srcImage, double kx, double ky)
{
	int rows = cvRound(srcImage.rows * kx);
	int cols = cvRound(srcImage.cols * ky);
	Mat resultImg(rows, cols, srcImage.type());
	int i, j;
	int xm, ym;
	int x0, y0, xi, yi, x1, y1, x2, y2;
	float wx0, wy0, wxi, wyi, wx1, wy1, wx2, wy2;
	float w00, w01, w02, w0i, w10, w11, w12, w1i, w20, w21, w22, w2i, wi0, wi1, wi2, wii;
	for (i = 0; i < rows; i++)
	{
		xm = i / kx;
		xi = (int)xm;
		x0 = xi - 1;
		x1 = xi + 1;
		x2 = xi + 2;
		wx0 = Bicubic(x0 - xm);
		wxi = Bicubic(xi - xm);
		wx1 = Bicubic(x1 - xm);
		wx2 = Bicubic(x2 - xm);
		for (j = 0; j < cols; j++)
		{
			ym = j / ky;
			yi = (int)ym;
			y0 = yi - 1;
			y1 = yi + 1;
			y2 = yi + 2;
			wy0 = Bicubic(y0 - ym);
			wyi = Bicubic(yi - ym);
			wy1 = Bicubic(y1 - ym);
			wy2 = Bicubic(y2 - ym);
			w00 = wx0*wy0;
			w01 = wx0*wy1;
			w02 = wx0*wy2;
			w0i = wx0*wyi;
			w10 = wx1*wy0;
			w11 = wx1*wy1;
			w12 = wx1*wy2;
			w1i = wx1*wyi;
			w20 = wx2*wy0;
			w21 = wx2*wy1;
			w22 = wx2*wy2;
			w2i = wx2*wyi;
			wi0 = wxi*wy0;
			wi1 = wxi*wy1;
			wi2 = wxi*wy2;
			wii = wxi*wyi;
			if ((x0 >= 0) && (x2 < srcImage.rows) && (y0 >= 0) && (y2 < srcImage.cols))
			{
				resultImg.at<Vec3b>(i, j) = (srcImage.at<Vec3b>(x0, y0)*w00 + srcImage.at<Vec3b>(x0, y1)*w01 + srcImage.at<Vec3b>(x0, y2)*w02 + srcImage.at<Vec3b>(x0, yi)*w0i
					+ srcImage.at<Vec3b>(x1, y0)*w10 + srcImage.at<Vec3b>(x1, y1)*w11 + srcImage.at<Vec3b>(x1, y2)*w12 + srcImage.at<Vec3b>(x1, yi)*w1i
					+ srcImage.at<Vec3b>(x2, y0)*w20 + srcImage.at<Vec3b>(x2, y1)*w21 + srcImage.at<Vec3b>(x2, y2)*w22 + srcImage.at<Vec3b>(x2, yi)*w2i
					+ srcImage.at<Vec3b>(xi, y0)*wi0 + srcImage.at<Vec3b>(xi, y1)*wi1 + srcImage.at<Vec3b>(xi, y2)*wi2 + srcImage.at<Vec3b>(xi, yi)*wii);
			}
		}
	}
	return resultImg;
}
————————————————
原文链接:https://blog.csdn.net/xuan_zizizi/article/details/82747729
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

双线性插值_亚像素边缘尺寸测量 的相关文章

  • python 浏览器模拟手机_Python selenium —— 用chrome的Mobile emulation模拟手机浏览器测试手机网页...

    很多人发现chrome有项功能 就是在开发者工具里能够模拟手机打开网页 便想能否用selenium对此进行自动化测试 答案当然是yes chrome emulation 今天博主便给大家分享下如何用chrome的MobileEmulatio
  • usb文档

    http www crifan com files doc docbook usb basic release htmls emulation html
  • SAMSUNG i535(Verizon版S3)不能使用电信3G网络的问题

    参考了好几篇文章最后解决了 参考文章如下 http www diypda com thread 1028813 1 1 html http bbs 189store com thread 66887 1 1 html http www di
  • 初学nodejs一:别被Express的API搞晕了

    初学nodejs 这个系列并不是入门系列 其实我自己还没入门 入门的话 推荐大家 1 一起学nodejs 2 BYVoid大神的 Node js开发指南 不过虽然是大神写的教程 也要带着怀疑的态度去看 这个系列 主要讲一些我初学nodejs
  • 星际战甲服务器维护时间,星际战甲 官网:2月4日服务器维护结束公告

    感谢各位玩家的耐心等待 目前服务器已维护完毕并已对外开放 玩家可以正常登录游戏 本次维护内容包括 新内容开放 断罪之影 活动开启时间 2021年2月4日中午12 00 阿拉德五世将发送邮件告知追猎者的使徒正在起源星系追杀天诺 开始断罪之影活
  • 基于onnxruntime的YOLOv5单张图片检测实现

    接上一篇 基于pytorch的YOLOv5单张图片检测实现 我们实现了pytorch的前向推理 但是这个推理过程需要依赖yolov5本身的模型文件以及结构搭建的过程 所以还是比较麻烦的 这里 有没有一个直接前向推理 然后只处理结果 无需考虑
  • 4.4.2分类模型评判指标(三) - KS曲线与KS值

    简介 KS曲线是用来衡量分类型模型准确度的工具 KS曲线与ROC曲线非常的类似 其指标的计算方法与混淆矩阵 ROC基本一致 它只是用另一种方式呈现分类模型的准确性 KS值是KS图中两条线之间最大的距离 其能反映出分类器的划分能力 一句话概括
  • Docker国内镜像源设置

    编辑json文件 添加如下内容后重启docker即可 root Docker cat etc docker daemon json registry mirrors http 18817714 m daocloud io 说明 json配置
  • 计算机专业知识要点,计算机专业基础知识要点及习题

    计算机专业基础知识要点及习题 第一章概论 数据就是指能够被计算机识别 存储和加工处理的信息的载体 数据元素是数据的基本单位 可以由若干个数据项组成 数据项是具有独立含义的最小标识单位 数据结构的定义 逻辑结构 从逻辑结构上描述数据 独立于计
  • CCF 2019年9月第一题--小明种苹果(java)

    此代码为提交满分代码 如有什么不好之处 欢迎留言 必认真研讨 试题编号 201909 1 试题名称 小明种苹果 时间限制 2 0s 内存限制 512 0MB 问题描述 package com hsx ccf import java util
  • .NET Framework各版本比较

    摘自CSDN 导读 一直以来 众多学校教学以及公司开发环境所使用Visual Studio NET Framework版本多不相同 本文作者比较了 NET Framework多个版本之间的区别 方便各位选择和切换 NET Framework
  • centos end trace

    每个人遇到的问题可能不一样吧 我也不是专业的运维 我只能说我自己的解决方法 错误 重启的时候出现的 百度 Google后感觉问题大概出现在内核版本上面在https www linuxquestions org questions slack
  • 写出一个抽奖页面,有200个人参加抽奖

    写出一个抽奖页面 有200个人参加抽奖 每次抽出一个人 不能重复 必须每个人都要抽中奖 前面10次抽奖要选中固定的10个人 每次就从这10人中随机抽取一人 不能重复 从第11次开始就从剩余的190人当中抽奖 不能重复 直到抽奖结束 已经中过
  • Java实现输出 1000 - 2000 之间所有的闰年

    我之前写过一篇文章 输出1 100之内的素数 其实是差不多的 可以参考一下 https blog csdn net question mark article details 100627185 关于闰年我们知道 有三种情况 分别是普通闰年
  • 软件测试/测试开发丨学习笔记之接口自动化测试

    本文为霍格沃兹测试开发学社学员学习笔记分享 原文链接 https ceshiren com t topic 25120 一 接口自动化测试框架介绍 1 接口测试场景 2 自动化测试场景 3 接口自动化测试与 Web App 自动化测试区别
  • pands 表头字段自适应

    fields Unnamed 0 Unnamed 1 合计 人民币元 美元 合计 1 美元 1 沙特里亚尔 合计 2 人民币元 1 美元 2 沙特里亚尔 1 合计 3 美元 3 沙特里亚尔 2 cleaned sentence a 0 wh
  • 大模型时代,如何评估人工智能与人类智能?

    省时查报告 专业 及时 全面的行研报告库 省时查方案 专业 及时 全面的营销策划方案库 免费下载 2023年8月份全网热门报告合集 ChatGPT提词示例 让你的ChatGPT聪明100倍 超百页干货资料 AI应用的难点 痛点与未来 202
  • 软件测试最新项目合集【商城、外卖、银行、金融等等.......】

    项目一 ShopNC商城 项目概况 ShopNC商城是一个电子商务B2C电商平台系统 功能强大 安全便捷 适合企业及个人快速构建个性化网上商城 包含PC IOS客户端 Adroid客户端 微商城 系统PC 后台是基于ThinkPHP MVC
  • 同一个网站可以放2个服务器吗,两个网站放在同一个服务器 备案

    两个网站放在同一个服务器 备案 内容精选 换一换 介绍常见的安全组配置示例 如下示例中 出方向默认全通 仅介绍入方向规则配置方法 允许外部访问指定端口不同安全组内的弹性云服务器内网互通仅允许特定IP地址远程连接弹性云服务器SSH远程连接Li

随机推荐

  • python语法(高阶)-多线程编程

    演示多线程编程的使用 import time import threading def sing msg while True print msg time sleep 1 return None def dance msg while T
  • vue2+koa2+mongodb分页

    后端 const Koa require koa2 const Router require koa router const Monk require monk 链接mongodb数据库中间件 const app new Koa cons
  • 导入数据库

    导入数据库 数据库表 打开SQL Server数据库 选择数据库单击右键新建一个数据库表
  • Selenium爬虫实战丨Python爬虫实战系列(8)

    个人主页 互联网阿星 格言 选择有时候会大于努力 但你不努力就没得选 作者简介 大家好我是互联网阿星 和我一起合理使用Python 努力做时间的主人 如果觉得博主的文章还不错的话 请点赞 收藏 留言 支持一下博主哦 行业资料 PPT模板 简
  • 每天进步一点点-WPF-根据数据类型加载控件

    目的 根据数据类型的不同 动态的加载适用于不同数据类型的控件 布局 原理 为自定义的数据类型添加数据魔板 绑定的时候绑定这些数据类型的实例 例子 数据类型 数据模板
  • 达尔文商品管理

    什么是达尔文 达尔文是一套全新的商品管理体系 它不同于淘宝原来的分类法 基于类目属性体系 的管理思路 而是以最细粒度的产品节点 CSPU 为核心 使用系统 运营机制的方式维护一套丰富 准确的产品库 通过产品实现聚合 管控商品 以确保商品信息
  • Spring中typeAliasesPackage的作用

    typeAliasesPackage 是自动配置别名 也就是设置这个之后 在Mybatis的Mapper文件里就可以写对应的类名 而不用写全路径名了 例如 typeAliasesPackage xyz hashdog modules bea
  • UE4物体随着样条线(Spline)运动

    1 样条线原理 1 1 贝塞尔曲线 一定要经过起止点 若干个控制点用于控制曲线弯曲的方向 最终形成一条光滑的曲线 由于贝塞尔曲线点太多了不好控制 一般每四个点做一次贝塞尔曲线 得到的若干段相邻贝塞尔曲线的连接点需要共线且距离相同 即为C1连
  • Java 菜鸟入门

    前言 所谓进制转换 就是人们利用符号来计数的方法 进制转换由一组数码符号和两个基本因素 基数 和 位权 所构成 其中基数是指进位计数制中所采用的数码的个数 逢 n 进 1 中的 n 就是基数 而位权则指的是进位制中每一个固定位置所对应的单位
  • Vue PostCss插件——autoprefixer配置完成后无效,已解决

    在使用autoprefixer时 先前的配置能成功添加css浏览器前缀 但结合postcss pxtorem插件后 px可以转换为rem 但css前缀无效 经过几个小时的鼓捣 终于让我发现了蛛丝马迹 哈哈哈 好开心 好激动 一起来看一看博主
  • Vue.js面试题

    目录 1 如何再Vue的单文件组件里的样式定义全局CSS 2 vue router 3 1 0
  • C语言itoa函数实现-数字面值转字符串

    数字面值转字符串 思路 首先判断是否为负数若是则转为正数 将待转换的int类型值每次对10取余获得最低位的数字 将该数字转为字符面值 然后将int类型值除以10 直到等于0结束循环 此时由于是从int类型值的最低位开始取得 所以转换出来的字
  • Vulkan-实践第一弹

    上一篇文章中 我们浅析了Vulkan对传统图形API的优势 主要就是在其性能和精细化操控GPU上 具体可参考Vulkan 性能及精细化 今天我们就来用个简单的例子 亲身感受下Vulkan的开发 魅力 include
  • 网络安全——SQL注入漏洞

    一 SQL注入概述 1 SQL注入漏洞 攻击者利用Web应用程序对用户输入验证上的疏忽 在输入的数据中包含对某些数据库系统有特殊意义的符号或命令 让攻击者有机会直接对后台数据库系统下达指令 进而实现对后台数据库乃至整个应用系统的入侵 2 S
  • 代码审计-弱类型整数大小比较绕过

    temp GET password is numeric temp die no numeric NULL if temp gt 1336 echo flag is numeric 同样可以用数组绕过 00截断 添加其他字符 http 12
  • 为何我的请求报错handshake_failure

    这两天被httpclient发送https请求烦死了老是失败 今天终于连通的于是来说说这几天遇到的坑 首先是域名 因为配置的是公网域名和地址 原来的工程内网用ip访问是不行的 在验证host的时候会给错误不让连 解决方案是修改本机hosts
  • LaTeX学习笔记(表格操作)

    1 创建tabular表格 使用如下语句创建表格 且创建表格时必须声明表格中各元素对其方式 有几列就需要几个对其参数 begin tabular clr c为居中对其 l为左对齐 r为右对齐 表格数据 end tabular 注 表格中用
  • python虚拟环境,conda的安装与使用

    axiner 声明 错了另刂扌丁我 如若有误 记得评论指出 谢谢了 简介 Conda 是一种通用包管理系统 当然包含管理Python 支持linux mac win Anaconda 是一个开源的Python发行版 包含了conda pyt
  • 微信小程序简洁登录页面(附源码)

    文章目录 1 登录页面 2 用户不存在 3 代码 3 1 login wxml 3 2 login css 3 3 login js 4 斜体样式 总结 1 登录页面 登录的具体流程 1 当用户输入密码和账号后首先检验账号和密码是否为空 2
  • 双线性插值_亚像素边缘尺寸测量

    读了好几篇关于亚像素边缘的博客 记录几点收获总结 若有错 还请读者朋友指正 亚像素边缘常见的方法主要是插值法和拟合法 如 近邻插值 双线性插值 三次插值 最小二乘法拟合等 实际并不存在亚像素边缘坐标 可以通过放大或缩小图像获得原图像的亚像素