数字图像处理Python实现图像灰度变换、直方图均衡、均值滤波

数字图像处理Python实现图像灰度变换、直方图均衡、均值滤波,第1张

import CV2

import copy

import numpy as np

import random

使棚轮用的是pycharm

因为最近看了《银翼杀手2049》,里面Joi实在是太好看了所以链镇信原图像就用Joi了

要求是灰度图像,所以第一步先把图像转化成灰度图像

# 读入原始图像

img = CV2.imread('joi.jpg')

# 灰度化处理

gray = CV2.cvtColor(img, CV2.COLOR_BGR2GRAY)

CV2.imwrite('img.png', gray)

第一个任务是利用分段函数增强灰度对比,我自己随便写了个函数大致是这样的

def chng(a):

if a <255/3:

b = a/2

elif a <255/3*2:

b = (a-255/3)*2 + 255/6

else:

b = (a-255/3*2)/2 + 255/6 +255/3*2

return b

rows = img.shape[0]

cols = img.shape[1]

cover = copy.deepcopy(gray)

for i in range(rows):

for j in range(cols):

cover[i][j] = chng(cover[i][j])

CV2.imwrite('cover.png', cover)

下一步是直方图均衡化

# histogram equalization

def hist_equal(img, z_max=255):

H, W = img.shape

# S is the total of pixels

S = H * W * 1.

out = img.copy()

sum_h = 0.

for i in range(1, 255):

ind = np.where(img == i)

sum_h += len(img[ind])

z_prime = z_max / S * sum_h

out[ind] = z_prime

out = out.astype(np.uint8)

return out

covereq = hist_equal(cover)

CV2.imwrite('covereq.png', covereq)

在实现滤波之前先添加高斯噪声和椒盐噪声(代码来源旅兆于网络)

不知道这个椒盐噪声的名字是谁起的感觉隔壁小孩都馋哭了

用到了random.gauss()

percentage是噪声占比

def GaussianNoise(src,means,sigma,percetage):

NoiseImg=src

NoiseNum=int(percetage*src.shape[0]*src.shape[1])

for i in range(NoiseNum):

randX=random.randint(0,src.shape[0]-1)

randY=random.randint(0,src.shape[1]-1)

NoiseImg[randX, randY]=NoiseImg[randX,randY]+random.gauss(means,sigma)

if NoiseImg[randX, randY]<0:

NoiseImg[randX, randY]=0

elif NoiseImg[randX, randY]>255:

NoiseImg[randX, randY]=255

return NoiseImg

def PepperandSalt(src,percetage):

NoiseImg=src

NoiseNum=int(percetage*src.shape[0]*src.shape[1])

for i in range(NoiseNum):

randX=random.randint(0,src.shape[0]-1)

randY=random.randint(0,src.shape[1]-1)

if random.randint(0,1)<=0.5:

NoiseImg[randX,randY]=0

else:

NoiseImg[randX,randY]=255

return NoiseImg

covereqg = GaussianNoise(covereq, 2, 4, 0.8)

CV2.imwrite('covereqg.png', covereqg)

covereqps = PepperandSalt(covereq, 0.05)

CV2.imwrite('covereqps.png', covereqps)

下面开始均值滤波和中值滤波了

就以n x n为例,均值滤波就是用这n x n个像素点灰度值的平均值代替中心点,而中值就是中位数代替中心点,边界点周围补0;前两个函数的作用是算出这个点的灰度值,后两个是对整张图片进行

#均值滤波模板

def mean_filter(x, y, step, img):

sum_s = 0

for k in range(x-int(step/2), x+int(step/2)+1):

for m in range(y-int(step/2), y+int(step/2)+1):

if k-int(step/2) 0 or k+int(step/2)+1 >img.shape[0]

or m-int(step/2) 0 or m+int(step/2)+1 >img.shape[1]:

sum_s += 0

else:

sum_s += img[k][m] / (step*step)

return sum_s

#中值滤波模板

def median_filter(x, y, step, img):

sum_s=[]

for k in range(x-int(step/2), x+int(step/2)+1):

for m in range(y-int(step/2), y+int(step/2)+1):

if k-int(step/2) 0 or k+int(step/2)+1 >img.shape[0]

or m-int(step/2) 0 or m+int(step/2)+1 >img.shape[1]:

sum_s.append(0)

else:

sum_s.append(img[k][m])

sum_s.sort()

return sum_s[(int(step*step/2)+1)]

def median_filter_go(img, n):

img1 = copy.deepcopy(img)

for i in range(img.shape[0]):

for j in range(img.shape[1]):

img1[i][j] = median_filter(i, j, n, img)

return img1

def mean_filter_go(img, n):

img1 = copy.deepcopy(img)

for i in range(img.shape[0]):

for j in range(img.shape[1]):

img1[i][j] = mean_filter(i, j, n, img)

return img1

完整main代码如下:

if __name__ == "__main__":

# 读入原始图像

img = CV2.imread('joi.jpg')

# 灰度化处理

gray = CV2.cvtColor(img, CV2.COLOR_BGR2GRAY)

CV2.imwrite('img.png', gray)

rows = img.shape[0]

cols = img.shape[1]

cover = copy.deepcopy(gray)

for i in range(rows):

for j in range(cols):

cover[i][j] = chng(cover[i][j])

CV2.imwrite('cover.png', cover)

covereq = hist_equal(cover)

CV2.imwrite('covereq.png', covereq)

covereqg = GaussianNoise(covereq, 2, 4, 0.8)

CV2.imwrite('covereqg.png', covereqg)

covereqps = PepperandSalt(covereq, 0.05)

CV2.imwrite('covereqps.png', covereqps)

meanimg3 = mean_filter_go(covereqps, 3)

CV2.imwrite('medimg3.png', meanimg3)

meanimg5 = mean_filter_go(covereqps, 5)

CV2.imwrite('meanimg5.png', meanimg5)

meanimg7 = mean_filter_go(covereqps, 7)

CV2.imwrite('meanimg7.png', meanimg7)

medimg3 = median_filter_go(covereqg, 3)

CV2.imwrite('medimg3.png', medimg3)

medimg5 = median_filter_go(covereqg, 5)

CV2.imwrite('medimg5.png', medimg5)

medimg7 = median_filter_go(covereqg, 7)

CV2.imwrite('medimg7.png', medimg7)

medimg4 = median_filter_go(covereqps, 7)

CV2.imwrite('medimg4.png', medimg4)

多股票策略回测时常常遇到问题则扮。

仓位如何分配?

你以为基金经理都是一拍脑袋就等分仓位了吗?

或者玩点玄乎的斐波拉契数列?

OMG,谁说的黄金比例,让我看到你的脑袋(不削才怪)!!

其实,这个问题,好多好多年前马科维茨(Markowitz)我喜爱的小马哥就给出答案——投资组合理论。

根据这个理论,我们可孙败灶以对多资产的组合配置进行三方面的优化。

1.找到有效前沿。在既定的收益率下使组合的方差最小。

2.找到sharpe最优的组合(收益-风险均衡点)

3.找到风险最小的组合

跟着我,一步两步,轻松实现。

该理论基于用均值和方差来表述组合的优劣的前提。将选取几只股票,用蒙特卡洛模拟初步探究组合的有效前沿。

通过最大Sharpe和最小方差两种优化来找到最优的资产组合配置权重参数。

最后,刻画出可能的分布,两种最优以及组合的有效前沿。

注:

文中的数据API来自量化平台聚宽,在此表示感谢。

原文见【组合管理】——投资组合理论(有效前沿)(包含正态检验部分)

0.导入需要的包

import pandas as pd

import numpy as np

import statsmodels.api as sm #统计运算

import scipy.stats as scs #科学计算

import matplotlib.pyplot as plt #绘图

1.选取几只感兴趣的股票

000413 东旭光电,000063 中兴通讯,002007 华兰生物,000001 平安银行,000002 万科A

并比较一下数据(2015-01-01至2015-12-31)

In[1]:

stock_set = ['000413.XSHE','000063.XSHE','002007.XSHE','000001.XSHE','000002.XSHE']

noa = len(stock_set)

df = get_price(stock_set, start_date = '2015-01-01', end_date ='2015-12-31', 'daily', ['close'])

data = df['close']

#规范化后时序数据

(data/data.ix[0]*100).plot(figsize = (8,5))

Out[1]:

2.计算不同证券的均值、协方差

每年252个交易日,用每日收益得到年化收益。计算投资资产的协方差是构建资产组合过程的核心部分。运用pandas内置方法生产协方差矩阵。

In [2]:

returns = np.log(data / data.shift(1))

returns.mean()*252

Out[2]:

000413.XSHE 0.184516

000063.XSHE 0.176790

002007.XSHE 0.309077

000001.XSHE -0.102059

000002.XSHE 0.547441

In [3]:

returns.cov()*252

Out[3]:

3.给不同资产随机分配初始权重

由于A股不允许建立空头头寸,所有的权重系数均在0-1之间

In [4]:

weights = np.random.random(noa)

weights /= np.sum(weights)

weights

Out[4]:

array([ 0.37505798, 0.21652754, 0.31590981, 0.06087709, 0.03162758])

4.计算预期组合年化收益、组合方差和组合标准差

In [5]:

np.sum(returns.mean()*weights)*252

Out[5]:

0.21622558669017816

In [6]:

np.dot(weights.T, np.dot(returns.cov()*252,weights))

Out[6]:

0.23595133640121463

In [7]:

np.sqrt(np.dot(weights.T, np.dot(returns.cov()* 252,weights)))

Out[7]:

0.4857482232609962

5.用蒙特卡洛模拟产生大量随机组合

进行到此,我们最想知道的是给定的一个股票池(证券组合)如何找到风险和收益平衡的位置。

下面通过一次蒙特卡洛模拟,产生大量随机的枯型权重向量,并记录随机组合的预期收益和方差。

In [8]:

port_returns = []

port_variance = []

for p in range(4000):

weights = np.random.random(noa)

weights /=np.sum(weights)

port_returns.append(np.sum(returns.mean()*252*weights))

port_variance.append(np.sqrt(np.dot(weights.T, np.dot(returns.cov()*252, weights))))

port_returns = np.array(port_returns)

port_variance = np.array(port_variance)

#无风险利率设定为4%

risk_free = 0.04

plt.figure(figsize = (8,4))

plt.scatter(port_variance, port_returns, c=(port_returns-risk_free)/port_variance, marker = 'o')

plt.grid(True)

plt.xlabel('excepted volatility')

plt.ylabel('expected return')

plt.colorbar(label = 'Sharpe ratio')

Out[8]:

6.投资组合优化1——sharpe最大

建立statistics函数来记录重要的投资组合统计数据(收益,方差和夏普比)

通过对约束最优问题的求解,得到最优解。其中约束是权重总和为1。

In [9]:

def statistics(weights):

weights = np.array(weights)

port_returns = np.sum(returns.mean()*weights)*252

port_variance = np.sqrt(np.dot(weights.T, np.dot(returns.cov()*252,weights)))

return np.array([port_returns, port_variance, port_returns/port_variance])

#最优化投资组合的推导是一个约束最优化问题

import scipy.optimize as sco

#最小化夏普指数的负值

def min_sharpe(weights):

return -statistics(weights)[2]

#约束是所有参数(权重)的总和为1。这可以用minimize函数的约定表达如下

cons = ({'type':'eq', 'fun':lambda x: np.sum(x)-1})

#我们还将参数值(权重)限制在0和1之间。这些值以多个元组组成的一个元组形式提供给最小化函数

bnds = tuple((0,1) for x in range(noa))

#优化函数调用中忽略的唯一输入是起始参数列表(对权重的初始猜测)。我们简单的使用平均分布。

opts = sco.minimize(min_sharpe, noa*[1./noa,], method = 'SLSQP', bounds = bnds, constraints = cons)

opts

Out[9]:

status: 0

success: True

njev: 4

nfev: 28

fun: -1.1623048291871221

x: array([ -3.60840218e-16, 2.24626781e-16, 1.63619563e-01, -2.27085639e-16, 8.36380437e-01])

message: 'Optimization terminated successfully.'

jac: array([ 1.81575805e-01, 5.40387481e-01, 8.18073750e-05, 1.03137662e+00, -1.60038471e-05, 0.00000000e+00])

nit: 4

得到的最优组合权重向量为:

In [10]:

opts['x'].round(3)

Out[10]:

array([-0. , 0. , 0.164, -0. , 0.836])

sharpe最大的组合3个统计数据分别为:

In [11]:

#预期收益率、预期波动率、最优夏普指数

statistics(opts['x']).round(3)

Out[11]:

array([ 0.508, 0.437, 1.162])

7.投资组合优化2——方差最小

接下来,我们通过方差最小来选出最优投资组合。

In [12]:

#但是我们定义一个函数对 方差进行最小化

def min_variance(weights):

return statistics(weights)[1]

optv = sco.minimize(min_variance, noa*[1./noa,],method = 'SLSQP', bounds = bnds, constraints = cons)

optv

Out[12]:

status: 0

success: True

njev: 7

nfev: 50

fun: 0.38542969450547221

x: array([ 1.14787640e-01, 3.28089742e-17, 2.09584008e-01, 3.53487044e-01, 3.22141307e-01])

message: 'Optimization terminated successfully.'

jac: array([ 0.3851725 , 0.43591119, 0.3861807 , 0.3849672 , 0.38553924, 0. ])

nit: 7

方差最小的最优组合权重向量及组合的统计数据分别为:

In [13]:

optv['x'].round(3)

Out[13]:

array([ 0.115, 0. , 0.21 , 0.353, 0.322])

In [14]:

#得到的预期收益率、波动率和夏普指数

statistics(optv['x']).round(3)

Out[14]:

array([ 0.226, 0.385, 0.587])

8.组合的有效前沿

有效前沿有既定的目标收益率下方差最小的投资组合构成。

在最优化时采用两个约束,1.给定目标收益率,2.投资组合权重和为1。

In [15]:

def min_variance(weights):

return statistics(weights)[1]

#在不同目标收益率水平(target_returns)循环时,最小化的一个约束条件会变化。

target_returns = np.linspace(0.0,0.5,50)

target_variance = []

for tar in target_returns:

cons = ({'type':'eq','fun':lambda x:statistics(x)[0]-tar},{'type':'eq','fun':lambda x:np.sum(x)-1})

res = sco.minimize(min_variance, noa*[1./noa,],method = 'SLSQP', bounds = bnds, constraints = cons)

target_variance.append(res['fun'])

target_variance = np.array(target_variance)

下面是最优化结果的展示。

叉号:构成的曲线是有效前沿(目标收益率下最优的投资组合)

红星:sharpe最大的投资组合

黄星:方差最小的投资组合

In [16]:

plt.figure(figsize = (8,4))

#圆圈:蒙特卡洛随机产生的组合分布

plt.scatter(port_variance, port_returns, c = port_returns/port_variance,marker = 'o')

#叉号:有效前沿

plt.scatter(target_variance,target_returns, c = target_returns/target_variance, marker = 'x')

#红星:标记最高sharpe组合

plt.plot(statistics(opts['x'])[1], statistics(opts['x'])[0], 'r*', markersize = 15.0)

#黄星:标记最小方差组合

plt.plot(statistics(optv['x'])[1], statistics(optv['x'])[0], 'y*', markersize = 15.0)

plt.grid(True)

plt.xlabel('expected volatility')

plt.ylabel('expected return')

plt.colorbar(label = 'Sharpe ratio')

Out[16]:

一. 直方图均衡化:

        直方图均衡化是使图像直方图变得平坦的 *** 作。直方图均衡化能够有效地解决图像整体过暗、过亮的问题,增加图像的清晰度。

        具体流程如下所示。其中S是总的像素数,Zmax是像素的最大取值(8位灰度图像为255),h(i)为图像像素取值为 i 及 小于 i 的像素的总数。

二. python实现直方图均衡化 *** 作局敬

import cv2

import numpy as np

import matplotlib.pyplot as plt

# histogram equalization

def hist_equal(img, z_max=255):

        H, W = img.shape

        S = H * W  * 1.

        out = img.copy()

        sum_h = 0.

        for i in range(1, 255):

                ind = np.where(img == i)

                sum_h += len(img[ind])

                z_prime = z_max / S * sum_h

                out[ind] = z_prime

        out = out.astype(np.uint8)

        return out

# Read image

img = cv2.imread("../head_g_n.jpg",0).astype(np.float)

# histogram normalization

out = hist_equal(img)

# Display histogram

plt.hist(out.ravel(), bins=255, rwidth=0.8, range=(0, 255))

plt.show()

plt.savefig("out_his.png")

# Save result

cv2.imshow("result", out)

cv2.imwrite("out.jpg", out)

cv2.waitKey(0)

cv2.destroyAllWindows()

三. 实验结果:

        可以看到,直方图均衡化后的图像看起来比原来的图像更加清晰。对于图像亮度整体偏暗或者偏轿尺亮的图像,我们可以采用直方图均衡化的方法处理图像,使得它们看桐帆慎上去更加清晰。

四. matlab 实现图像直方图均衡化:

        可以参考一篇优秀的博文:         https://blog.csdn.net/Ibelievesunshine/article/details/79961027

五. 参考内容:

         https://www.cnblogs.com/wojianxin/p/12510797.html

         https://blog.csdn.net/Ibelievesunshine/article/details/104922449


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/8202370.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-14
下一篇 2023-04-14

发表评论

登录后才能评论

评论列表(0条)

保存