怎么用程序实现对数函数定义域域转化到实数域

数字图像处理-空间域图像增强(一)(图像反转,对数变换,幂次变换、分段线性变换)
空间域增强的第一部分:图像反转,对数变换,幂次变换、分段线性变换
(s:现点值,r: 原点值)
图像反转:
这个无需多说,就是把黑变白,白变黑,拿八位灰度图像来说
表达式:s=255-r
作用:看清暗色图像中白色和灰色的细节。
对数变换:
此变换使一窄带低灰度输入图像值映射为一宽带输出值。相对的是输入灰度的高调整值。可以利用这种变换来扩展被压缩的高值图像中的暗像素。相对的是反对数变换的调整值。(这段转自《数字图像处理》(第二版)(冈萨雷斯))
附:说的太透彻了,找不到比这更好的语言了
表达式:s=c log(1+r);
变换曲线:
应用:用于对数值范围过大的数据进行调整显示,如傅立叶变换后的图像数据(0-1.5e6).
幂次变换:
又叫伽玛校正,和对数变换的原理差不多,不多说了,只是参数多了一个,可变宽带的输入像素值范围可选了,把低值带拉伸还是把高值拉伸要看伽马的设定了。
表达式:(这个是图片格式,粘的太丑,不过不影响什么)
变换曲线:
一个是伽马等于4,一个是伽马等于0.2;一个拉伸高像素值的范围,一个拉伸低像素值的范围。哪部分的斜率越大,哪部分的拉伸比例就越大。
分段线性变换:
分为:对比拉伸、灰度切割、位图切割
位图切割就是比如8位的图像,我把像素点的每一位拿出来做个位平面,然后就有8个位平面了。
以上这几个处理方法都是将固定范围内的像素值的显示范围放大或缩小,让图像更符合人为意愿。
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!灰度对数变换
理论基础:
对数变换的一般表达式为:
t=c *log(1+s)
其中 c为尺度比例常数,s为原图灰度值,t 为变换后的目标灰度值。
对数变换示意图
有对数曲线可知,这种图像可以增强一幅图像中较暗部分的细节,从而可以用来扩展被压缩的高值图像中较暗像素,因此对数变换被广泛的应用于频谱图像的显示中。
代码如下:
void Ctry::OnTryTyr1()
在此添加命令处理程序代码
IplImage *img = cvLoadImage("C:\\Users\\Administrator\\Desktop\\55.jpg");
IplImage* r = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
IplImage* g = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
IplImage* b = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
cvSplit(img, r, g, b, NULL);
CvScalar pixel1;
double temp, temp1;
for (int i = 0; i & b-&height - 1; ++i)
for (int j = 0; j & b-&width - 1; ++j)
//pixel1 = cvGet2D(b, i, j);
temp1 = cvGet2D(b, i, j).val[0];
//对数变换
temp = 30 * log((double)(temp1 + 1));
cvSet2D(b, i, j, temp);
cvNamedWindow("bb", CV_WINDOW_AUTOSIZE);
cvShowImage("bb", b);
cvWaitKey(0);
cvReleaseImage(&img);
cvReleaseImage(&r);
cvReleaseImage(&g);
cvReleaseImage(&b);
原图: b通道图:
对数后的图:
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!OpenCV学习笔记(一)对数变换
关于对数变换,目的就是将输入图像中较窄的低灰度值映射到输出图像较宽的灰度值。s=log(1+r);
在程序中使用add(InputArray src1, InputArray src2,
OutputArray dst, InputArray mask=noArray(), int dtype=-1)
要实现r+1:add(InputImage,Scalar(1.0),OutputImage);
实现log(r+1):log(InputImage,OutputImage)。
这样就实现了对图像的对数变换。
实现方法有三种方式,详细的看程序,logTransform1基于源图像,logTransform2()和logTransform3()直接对目标进行操作。#include &opencv2/core/core.hpp&
#include &opencv2/highgui/highgui.hpp&
#include &opencv2/imgproc/imgproc.hpp&
#include &iostream&
//基于源图像的方法1
Mat logTransform1(Mat srcImage, int c)
if (srcImage.empty())
cout && "No data" &&
Mat resultImage = Mat::zeros(srcImage.size(), srcImage.type());
add(srcImage, Scalar(1.0), srcImage);
//计算 r+1
srcImage.convertTo(srcImage, CV_32F);
//转化为32位浮点型
log(srcImage, resultImage);
//计算log(1+r)
resultImage = c*resultI
//归一化处理
normalize(resultImage, resultImage, 0, 255, NORM_MINMAX);
convertScaleAbs(resultImage, resultImage);
return resultI
Mat logTransform2(Mat srcImage, float c)
if (srcImage.empty())
cout && "No data" &&
Mat resultImage = Mat::zeros(srcImage.size(), srcImage.type());
double gray = 0;
for (int i = 0; i & srcImage. i++)
for (int j = 0; j & srcImage. j++)
gray = (double)srcImage.at&uchar&(i, j);
gray = c*log((double)(1 + gray));
resultImage.at&uchar&(i, j) = saturate_cast&uchar&(gray);
//归一化处理
normalize(resultImage, resultImage, 0, 255, NORM_MINMAX);
convertScaleAbs(resultImage, resultImage);
return resultI
Mat logTransform3(Mat srcImage, float c)
if (srcImage.empty())
cout && "No data" &&
Mat resultImage = Mat::zeros(srcImage.size(), srcImage.type());
srcImage.convertTo(resultImage, CV_32F);
//图像类型转换
resultImage = resultImage + 1;
//图像矩阵元素加1
log(resultImage,resultImage);
resultImage = c*resultI
//归一化处理
normalize(resultImage, resultImage, 0, 255, NORM_MINMAX);
convertScaleAbs(resultImage, resultImage);
return resultI
int main()
Mat srcImage = imread("D:\\1.jpg");
if (!srcImage.data)
return -1;
imshow("srcImage", srcImage);
float c = 1.2;
Mat resultI
tTime = (double)getTickCount();
const int nTimes = 100;
for (int i = 0; i & nT i++)
resultImage = logTransform3(srcImage, c);
tTime = 1000 * ((double)getTickCount() - tTime) / getTickFrequency();
tTime /= nT
cout && tTime &&
imshow("resultImage", resultImage);
waitKey(0);
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!发现自己以前写的好垃圾
有限域和离散对数问题(ECC椭圆曲线算法2)
有限域和离散对数问题
这篇文章是ECC系列的第二篇
在上一篇文章中,我们看到了基于实数域的的椭圆曲线如何构成了群(Group),我们如下定义了群中的加法:P + Q + R = 0,我们分别用几何方法和代数方法计算了了椭圆曲线点的加法。
随后,我们有介绍了数乘(nP = P + P + P + … + P),然后找到了一个较为快速的计算nP的算法:double and add。
现在,我们要限制我们的椭圆曲线在有限域上(实数域不是有限域),而不是实数域,让我们来看看有哪些变化。
The field of integers modulo p
有限域,首先是一个拥有有限元素的几何。例如,一个简单的有限域就是以素数p为模数的数的集合(模P余数的集合,即模p剩余类环),常被写为Z/p,GF(P),Fp,我们在后文会这么描述一个模P的有限域。
在域中,我们有2种二元运算,加法 和 乘法,两者运算都是封闭的、满足结合律、分配率。两个运算都是唯一的单位元。并且对于每一个元素,都有唯一的逆元。最后,乘法对加法满足分配率:x *( y + z) = x*y + x*z.
整数模p的集合,包括了从0~p-1的数,加法和乘法的运算都是模p的。下面是F23例子。
加法:(18 + 9)mod 23 = 4
减法:(7 - 14) mod 23 = 16
乘法:4 * 7 mod 23 = 5
加法逆元: x + 5 = 0 mod 23 =& x= 18
乘法逆元: x *9 = 1 mod 23 =& x= 18
(上面两个例子和原文中不一样,个人觉得原文中举例不恰当。
作为加法群,单位元为0,作为乘法群,单位元为1。
乘法逆元使用欧几里得拓展算法可求x,即 9x - 23y = 1,辗转相除即可求得x值x = -5,去其最小正整数则为18。
上文已说过,如果p是素数,则模p剩余类环是域。P是素数很重要,如果p不是素数,比如p=4,则集合Zp={0, 1, 2, 3},显然2没有逆元。
2*1 mod 4 = 2
2*2 mod 4 = 0
2*3 mod 4 = 2
模p作用的除法运算
我们将要定义在Fp上的椭圆曲线,但是在这之前,我们需要弄清几点概念。
x/y代表什么?数论中,x/y表示 x* y^-1,即 x 乘上 y的逆元。所以除法运算分为两步:第一步求逆元,第二步计算乘法。
乘法逆元可以使用欧几里得拓展算法轻松的计算,这里不多讲欧几里得拓展算法的细节,只是贴出Python代码
def extended_euclidean_algorithm(a, b):
Returns a three-tuple (gcd, x, y) such that
a * x + b * y == gcd, where gcd is the greatest
common divisor of a and b.
This function implements the extended Euclidean
algorithm and runs in O(log b) in the worst case.
s, old_s = 0, 1
t, old_t = 1, 0
r, old_r = b, a
while r != 0:
quotient = old_r // r
old_r, r = r, old_r - quotient * r
old_s, s = s, old_s - quotient * s
old_t, t = t, old_t - quotient * t
return old_r, old_s, old_t
def inverse_of(n, p):
Returns the multiplicative inverse of
n modulo p.
This function returns an integer m such that
(n * m) % p == 1.
gcd, x, y = extended_euclidean_algorithm(n, p)
assert (n * x + p * y) % p == gcd
if gcd != 1:
# Either n is 0, or p is not a prime number.
raise ValueError(
'{} has no multiplicative inverse '
'modulo {}'.format(n, p))
return x % p
Fp上的椭圆曲线
现在,我们可以在Fp上来定义椭圆曲线,上篇文章中,椭圆曲线如下描述:
而现在变成了下面的描述:
当然,0依旧表示无限远的点,也即单位元;参数a、b在Fp上
上面四张图,分别是 曲线方程 Y^2≡x^3-7x+10(modp) 参数p取为19,97,127,487的几何图形。(显然,p越小,集合Fp中的元素越少,满足Fp的椭圆曲线的点也越少)
当然,我们也可以证明,在Fp上的椭圆曲线的点,构成阿贝尔群(交换群)。
在实数域,我们定义了三个“aligned”的点相加结果为0,P + Q+ R = 0,当然,该定义在Fp上也适用。实数域上“aligned”就是共线,但是Fp上,我们需要重新定义“aligned”。
Fp上,如果(x, y)满足方程(ax + by+ c ) mod p = 0,则这些(x, y)是共线的.
上图中,是椭圆曲线方程y^2 = X^3 - x + 3 mod 127 的所有点。
点P(16,20), Q(41, 120),则方程y = 4x + 83(mod 127) 和 椭圆曲线方程相交于点P。
当然,点的加法依旧保持了原有的性质:
(1):Q + 0 = 0 + Q = Q
(2):Q及其逆元-Q,实数域上他两关于X轴对称,但是在Fp上,-Q = (Xq, -Yq mod p)
(3):p + (-P) = 0
代数方法计算加法
计算点的等式和上篇文章中基本差不多,唯一的区别就是在等式中加上mod p.
其中,如果P不等于Q,则
如果P等于Q则
和在实数域的椭圆曲线点加法差不多吧,这可不是巧合。这个等式可以用于任何的域,除了F2、F3不适用。
几何方法计算加法
我们不会定义几何方法,实际上,这样的话我们会碰到一些问题。比如,上篇文章中,我们说了要计算p + p,我们需要获得点p和椭圆曲线的切线,但是由于点非连续,切线就没有意义了。
椭圆曲线的阶
我们说过,椭圆曲线定义在有限域上,这也意味着,椭圆曲线上的点也是有限的。所以我们引出了一个问题:一个椭圆曲线到底有多少个点。
首先我们定义“椭圆曲线上点的个数”为 椭圆曲线的 阶 (order)。
当然,把x暴力的从0遍历到 p-1 肯定不是一个好方法,意味它需要p个步骤,如果p很大,那就非常慢。
幸运的是,有一个快速的方法计算椭圆曲线的阶。
数乘和循环子群
在实数域中,乘法可以被定义成这样:
我们可以使用 dobule and add 算法来计算乘法,算法复杂度是O(logn)。
但是椭圆曲线上的乘法有一个非常有趣的性质。
假设 Y^2 = X^3 + 2x + 3 mod 97 和 其上的点P (3, 6),我们来计算一下nP:
nP的取值只有5个不一样的点(0, P, 2P, 3P, 4P),然后他们周期循环。明显的,椭圆曲线上的数乘和模运算类似:
1P = (3,6)
2P = (80, 10)
3P = (80, 87)
4P = (3, 91)
6P = (3, 6)
7P = (80, 10)
8P = (80, 87)
9P = (3, 91)
我们需要指出两件事,点P的倍数的结果只有出现5个点,其他的点从未出现;其次他们是周期出现的,所以我们可以这样描述:
对于任意的K,如下等式成立
(5k + 1)P = P
(5k + 2)P = 2P
(5k + 3)P = 3P
(5k + 4)P = 4P
当然,上面的多个等式可以写成一个等式
kP = (K mod 5) P
显然,上面的5个点的集合,运算是封闭的。
当然,不仅仅P有这样的性质,其他点也有类似的性质。
即,P的加法构成了一个群S,由于S属于G,故S是G的子群。
循环子群是ECC的基础。
我们可以问自己,由P生成的子群的阶是什么?
1:首先,我们已经定义了阶就是群中点的个数。在子群中也是这样的,但是我们可以换一种表达方式:子群的阶是最小能够使得nP=0的n。就像上文中给出的例子,n是5。
2:子群的阶和群的阶是有关系的。拉格朗日定理说明了,子群的阶是群的阶的因子。即如果N是群的阶,则其子群的阶n,则n|N。
上述向我们给出了一个找到子群的阶的方法
(1)计算群的阶N
(2)找出所有N的因子
(3)每个N的因子n,然后乘以P
(4)在3中,找出最小的n,使得满足nP = 0。则这个n是子群的阶。
例如,假设在F37上定义椭圆曲线 y^2 = X^3 - x + 3,显然群的阶可以轻松算出为N = 42,子群的阶是n 可能是 1,2,3,6,7,14,21,42。
设曲线上的点P(2, 3),由于P 不等于0、2P不等于0……7P等于0,故P的阶是7。即由P生成的子群的阶是7。
注意,“最小的n”是非常重要的。如果随机的遍历0 ~ 42,则很有可能遍历到14,14P也是0,但是14不是P的阶。
另外一个例子,在F29上定义一个椭圆曲线:y^2 = x^3 - x + 1 ,则椭圆曲线的阶为N=37,由于37是素数,所以其因子只有1和37。如果子群的阶为1,则显然,该子群包含一个点,该点就是0.如果子群的阶是37,则该子群就是parent群。
找一个基点
在ECC算法种,我们希望找到一个阶数较大的子群。
通常我们会选择一个椭圆曲线,然后计算它的阶N,选择一个较大的因子n,然后找一个合适的基点。也就是说,我们不是首先找一个基点,然后计算它的阶,而是相反,我们先找到一个合适的阶,然后找以这个数为阶的子群的生成元。
怎么找呢?
首先,拉格朗日揭示,h = N/n是一个整数(当然,n是N的因子),h有一个自己的名字:cofactor of the subgroup。
首先,每个椭圆曲线上的点P,NP = 0,因为N是P的阶n的倍数。
我们可以写成这样 n(hP) = 0。
假设n是一个素数(下篇文章会讲到为什么),我们令G= hP,则G就是子群的生成元。
我们总结一下:
1:计算椭圆曲线的阶N。
2:选择一个数n当成子群的阶。n应该是N的素因数
3:计算h = N/n
4:随机选择一个点P
5:计算G = hP
6:如果G是0,到第4步。否则,我们找到了这个基点。
n必须是素数,若非如此,则nP = 0不一定表示n是P的阶,因为P的阶可能是n的一个因子。
接下来我们需要考虑一个问题
如果我们知道了P和Q,Q是P的倍数,我们计算这个倍数k?
这个问题就是基于椭圆曲线的离散对数问题,他被认为是很难解的问题。
目前为止没有找到在多项式时间(Polynomial time)内能够解决这个的方法,同样的,这个难题也没有数学上的严格证明。
这个难题也和其他密码学中的离散对数问题类似,例如DSA算法,DH密钥交换算法,ElGamal 算法,他们名字基本类似不是没有原因的,因为都是基于离散对数问题。只是上述例子中,使用了模幂运算,而不是我们椭圆曲线的数乘运算。
模幂运算的离散对数问题可以这么描述:
我们知道a 和 b是有这么一个等式关系 b = a^k mod p,给你一个a,b,p,让你求k。当然不管是模幂运算的DH还是椭圆曲线数乘的DH,他们的值都是离散的。因为值都取自于有限集合(子群),称之为对数,因为你要计算这个难题,需要对数运算。
ECC有趣的地方就是,它的离散对数问题,看起来比其他的离散对数问题难多了,这也意味着,在椭圆曲线算法中,我们可以使用更小的值k,来达到其他离散对数难题中同样的安全效果。
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!【图文】对数函数图象及性质――定义域、值域_百度文库
您的浏览器Javascript被禁用,需开启后体验完整功能,
赠送免券下载特权
10W篇文档免费专享
部分付费文档8折起
每天抽奖多种福利
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
对数函数图象及性质――定义域、值域
总评分3.9|
用知识赚钱
阅读已结束,下载本文到电脑
想免费下载本文?
登录百度文库,专享文档复制特权,积分每天免费拿!
你可能喜欢

我要回帖

更多关于 对数函数定义域值域 的文章

 

随机推荐