python正则表达式
展开阅读
展开阅读
python中的
p=re.compile(r"")
p.match("...")
只会从头匹配到尾,一般用于split之后的token的匹配,因此一般使用re.findall("...")
,或直接替换用re.sub()
给定类似[!abc](sfsdfsdf)abc
类型的字符串,如何把它替换成$abc
?
s=re.sub(r"\!\[(.*)\]\(.*?\)\1",r"$\1$",s)
其中要对!
,[]
,()
进行转义,使用?
取消greedy模式,并可以在用来替换的raw字符串中使用capture到的group
展开阅读
?
表示单个字符;*
(star)表示任意数量的字符;**
(global star)表示递归地匹配任意数量的字符,包括/
;[aeiou]
和正则表达式意义相同,但是匹配失败时会escape变回原意;[!aeiou]
表示除了aeiou;{aeiou}
匹配失败时不会变回原意,并且可以嵌套其他通配符,{a..z}
匹配a到z
通配符是先解释,再执行。不匹配时,会原样输出。只适用于单层路径(除了global star)。文件名中可能出现通配符。
展开阅读
初始化动态二维矩阵
#include<stdio.h>
#include<stdlib.h>
int** matrix(int height,int width,int initial)
{
int **a=malloc(sizeof *a * height);
printf("Initializing matrix of size %d X %d with initial value %d\n", height,width,initial);
for(int i=0;i<height;i++)
{
a[i]=malloc(sizeof *(a[i]) * width);
for(int j=0;j<width;j++)
{
a[i][j]=initial;
}
}
printf("Printing the matrix...\n");
for(int i=0;i<height;i++)
{
for(int j=0;j<width;j++)
{
printf("%d ",a[i][j]);
}
printf("\n");
}
}
int main(void)
{
int** m=matrix(4,5,0);
return 0;
}
分析复杂变量声明
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#define MAXTOKEN 100
enum { NAME, PARENS, BRACKETS};
void dcl(void);
void dirdcl(void);
int gettoken(void);
int tokentype;
char token[MAXTOKEN];
char name[MAXTOKEN];
char datatype[MAXTOKEN];
char out[1000];
main()
{
while (gettoken() != EOF) {
strcpy(datatype, token);
out[0] = '\0';
dcl();
if (tokentype != '\n')
printf("syntax error\n");
printf("%s: %s %s\n", name, out, datatype);
}
return 0;
}
/* dcl: parse a declarator */
void dcl(void)
{
int ns;
for (ns = 0; gettoken() == '*'; ) /* count *'s */
ns++;
dirdcl();
while (ns-- > 0)
strcat(out, " pointer to");
}
/* dirdcl: parse a direct declarator */
void dirdcl(void)
{
int type;
if (tokentype == '(') { /* ( dcl ) */
dcl();
if (tokentype != ')')
printf("error: missing )\n");
} else if (tokentype == NAME) /* variable name */
strcpy(name, token);
else
printf("error: expected name or (dcl)\n");
while ((type=gettoken()) == PARENS || type == BRACKETS)
if (type == PARENS)
strcat(out, " function returning");
else {
strcat(out, " array");
strcat(out, token);
strcat(out, " of");
}
}
int gettoken(void)
{
int c, getch(void);
void ungetch(int);
char *p = token;
while ((c = getch()) == ' ' || c == '\t')
;
if (c == '(') {
if ((c = getch()) == ')') {
strcpy(token, "()");
return tokentype = PARENS;
} else {
ungetch(c);
return tokentype = '(';
}
} else if (c == '[') {
for (*p++ = c; (*p++ = getch()) != ']'; )
;
*p = '\0';
return tokentype = BRACKETS;
} else if (isalpha(c)) {
for (*p++ = c; isalnum(c = getch()); )
*p++ = c;
*p = '\0';
ungetch(c);
return tokentype = NAME;
} else
return tokentype = c;
}
#define BUFSIZE 100
char buf[BUFSIZE];
int bufp = 0;
int getch(void)
{
return (bufp >0) ? buf[--bufp] : getchar();
}
void ungetch(int c)
{
if (bufp >= BUFSIZE)
printf("üngetch: too many characters\n");
else
buf[bufp++] = c;
}
打印进度条
void progress_bar(const int n, const int tot)
{
int i, pgr = n*50/tot, rem = (tot-n)*50/tot;
printf("\r[");
for (i=0; i<pgr; i++)
printf("#");
for (i=0; i<rem; i++)
printf("-");
printf("]");
}
lambda表达式
#define lambda(lambda$_ret, lambda$_args, lambda$_body)\
// 语句表达式
({\
lambda$_ret lambda$__anon$ lambda$_args\
lambda$_body\
lambda$__anon$;\ // 返回值
})
注释切换代码
#include<stdio.h>
int main(){
/**
printf("1\n");
/*/
printf("2\n");
//*/
/**/
printf("3\n");
/*/
printf("4\n");
//*/
return 0;
}
展开阅读
录制宏
qq
x
x
<Esc>
q
执行宏
@q
分屏
:sp filename
:vsp filename
<Ctrl + w>
v
<Ctrl + w>
s
<Ctrl + w>
h
<Ctrl + w>
l
<Ctrl + w>
j
<Ctrl + w>
k
跳转到历史编辑位置
<Ctrl + o>
<Ctrl + i>
在当前目录下的文件的内容中递归地搜索abc,跳转到下一个搜索到的内容
:vimgrep abc **/*.*
:cnext
删除到第20行
d20G
跳转到上一段,下一段
{
}
防止粘贴引起缩进混乱
:set paste
不退出vim编译运行代码
:!gcc test.c
:! a
编辑多行
<Ctrl-v>
"move to the last line
<Shift-I>
"edit
<Esc>
加密文件
:X
"输入密码
自动补全<Ctrl-n>
合并多个行
按V并移动,选中要合并的行
:j
合并两行:<Shift-j>
在新tab中打开文件
:tabnew filename
跳转tab
gt
gT
把制表符换成空格
:retab
比较文件
vimdiff file1 file2
:vert diffsplit file2
<Ctrl-u> 向上跳转
<Ctrl-d> 向下跳转
<Ctrl-f> 向前跳转
<Ctrl-b> 向后跳转
手动安装插件
:set runtimepath? "如果怕麻烦直接粘贴到这里的任一路径中
"set runtimepath^=~/.vim/bundle/ctrlp.vim "或添加到.vimrc里
查找替换
:{作用范围}s/{目标}/{替换}/{替换标志}
:%s/foo/bar/g
"替换当前行及之后共3行中的内容
:.,.+3s/foo/bar/g
重构代码
"跳转到变量定义处
gd
"跳转到上一个大括号
[{
"跳转到互补的括号
%
"生成当前搜索正在使用的正则表达式
<Ctrl-r>/
"使用ctags生成代码索引
!ctags -R
"跨文件查找定义位置
<Ctrl-]>
"返回旧的文件
<Ctrl-t>
"sudo apt install global #使用gtags生成索引
"gtags -v
:set csprg=gtags-cscope
:cs add GTAGS
在用Ctrl-V选中的Visual Block中查找替换
"替换掉Visual Block中所有空格
"在选中后按:
:'<,'>s/\%V\s\%V//g
查看二进制文件
:set binary
:%!xxd -p
:%!xxd -p -r
:w
切换编码格式
:set enc " 查看当前编码格式
:e ++enc=cp1252 " 重载为masm32 editor默认编码
:e ++enc=gb2312 " 重载为windows汉字编码
:w ++enc=utf-8 " 保存为utf-8格式
自动补全与拼写检查
:set spell spelllang=en " 打开拼写检查
:set nospell " 关闭拼写检查
]s " 找到下一个错误拼写单词
z= " 拼写建议
zg " 把未识别单词加入字典
<Ctrl-n> "<Ctrl-p> 自动补全
undo tree
:earlier 10 " 恢复到10分钟之前的状态
:later 10 " 恢复到10分钟之后的状态
g- " 按时间向前恢复
g+ " 按时间向后恢复
输入希腊字母
<Ctrl-k>
t*
配置文件
syntax enable
set expandtab
set smarttab
set shiftwidth=4
set tabstop=4
set ai
set si
set wrap
set fileencodings=ucs-bom,utf-8,utf-16,gb2312,gbk,big5,gb18030,latin1
set encoding=utf8
filetype plugin on
filetype indent on
set history=5000
set autoread
set so=7
let $LANG='en'
set langmenu=en
set ruler
set nu
set hid
set ignorecase
set smartcase
set hlsearch
set incsearch
set lazyredraw
set magic
set showmatch
set mouse=a
set undofile
set undodir=~/.vim/undodir
set backupdir=~/.vim/backupdir
set directory=~/.vim/swapdir
set noerrorbells
set novisualbell
"set spell spelllang=en
set autochdir
colorscheme industry
"以下为rust-analyzer和ALE插件
filetype plugin indent on
let g:ale_linters = {'rust': ['analyzer']}
set completeopt=menu,menuone,preview,noselect,noinsert
let g:ale_completion_enabled = 1
"以下为cscope需要的设置
set csprg=gtags-cscope
set cscopequickfix=s-,c-,d-,i-,t-,e-
set csto=0
set cscopetag
set cst
if filereadable("GTAGS")
cs add GTAGS
elseif $CSCOPE_DB != ""
cs add $CSCOPE_DB
endif
set tags=./tags,tags;
" 记住上次打开的位置
if has("autocmd")
au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
endif
展开阅读
import numpy as np
import cv2
def zmMinFilterGray(src, r=7):
'''最小值滤波,r是滤波器半径'''
return cv2.erode(src, np.ones((2*r+1, 2*r+1)))
def guidedfilter(I, p, r, eps):
'''引导滤波,直接参考网上的matlab代码'''
height, width = I.shape
m_I = cv2.boxFilter(I, -1, (r,r))
m_p = cv2.boxFilter(p, -1, (r,r))
m_Ip = cv2.boxFilter(I*p, -1, (r,r))
cov_Ip = m_Ip-m_I*m_p
m_II = cv2.boxFilter(I*I, -1, (r,r))
var_I = m_II-m_I*m_I
a = cov_Ip/(var_I+eps)
b = m_p-a*m_I
m_a = cv2.boxFilter(a, -1, (r,r))
m_b = cv2.boxFilter(b, -1, (r,r))
return m_a*I+m_b
def getV1(m, r, eps, w, maxV1): #输入rgb图像,值范围[0,1]
'''计算大气遮罩(暗通道)图像V1和光照值A, V1 = 1-t/A'''
V1 = np.min(m,2) #得到暗通道图像
#V1 = inverse_color_01(V1)
# cv2.imshow("dark channel", V1)
# cv2.waitKey(0)
V1 =guidedfilter(V1, zmMinFilterGray(V1,7), r, eps) #使用引导滤波优化
bins = 2000
ht = np.histogram(V1, bins) #计算大气光照A
d = np.cumsum(ht[0])/float(V1.size)
for lmax in range(bins-1, 0, -1):
if d[lmax]<=0.999:
break
A = np.mean(m,2)[V1>=ht[1][lmax]].max()
V1 = np.minimum(V1*w, maxV1) #对值范围进行限制
return V1,A
def deHaze(m, r=81, eps=0.001, w=0.95, maxV1=0.80):
Y = np.zeros(m.shape)
V1,A = getV1(m, r, eps, w, maxV1) #得到遮罩图像和大气光照
for k in range(3):
Y[:,:,k] = (m[:,:,k]-V1)/(1-V1/A) #颜色校正
Y = np.clip(Y, 0, 1)
return Y
def interpo(x, middle_ratio, max_x, max_num):
# 自定义的直方图
#| /\
#| / \
#| / \
#|/____ratio___\___
#
if not 0<=x<=max_x:
return 0
elif x<middle_ratio*max_x:
return int(max_num/(middle_ratio*max_x)*x)+1
else:
return int(max_num - max_num/(255-middle_ratio*max_x)*(x-middle_ratio*max_x))+1
def func(ratio):
# 使用自定义的直方图曲线func()生成直方图实例化图像
ret = []
for i in range(256):
ret = ret + [i]*interpo(i, ratio, 255, 1000)
return np.array(ret)
def find_nearest_above(my_array, target):
diff = my_array - target
mask = np.ma.less_equal(diff, -1)
# We need to mask the negative differences
# since we are looking for values above
if np.all(mask):
c = np.abs(diff).argmin()
return c # returns min index of the nearest if target is greater than any value
masked_diff = np.ma.masked_array(diff, mask)
return masked_diff.argmin()
def hist_match(original, specified):
oldshape = original.shape
original = original.ravel()
specified = specified.ravel()
# get the set of unique pixel values and their corresponding indices and counts
s_values, bin_idx, s_counts = np.unique(original, return_inverse=True,return_counts=True)
t_values, t_counts = np.unique(specified, return_counts=True)
# Calculate s_k for original image
s_quantiles = np.cumsum(s_counts).astype(np.float64)
s_quantiles /= s_quantiles[-1]
# Calculate s_k for specified image
t_quantiles = np.cumsum(t_counts).astype(np.float64)
t_quantiles /= t_quantiles[-1]
# Round the values
sour = np.around(s_quantiles*255)
temp = np.around(t_quantiles*255)
# Map the rounded values
b=[]
for data in sour[:]:
b.append(find_nearest_above(temp,data))
b= np.array(b,dtype='uint8')
return b[bin_idx].reshape(oldshape)
def hist_match_all(img):
# 对图像的每个通道都进行直方图规定化,使用func()中定义的直方图进行规定
result = np.zeros_like(img)
for i in range(3):
specified = func(0.2)
result[:,:,i] = hist_match(img[:,:,i], specified)
return result
def image_hist(image): #画三通道图像的直方图
color = ("blue", "green", "red")#画笔颜色的值可以为大写或小写或只写首字母或大小写混合
for i, color in enumerate(color):
hist = cv2.calcHist([image], [i], None, [256], [0, 256])
plt.plot(hist, color=color)
plt.xlim([0, 256])
plt.show()
def normalize(img):
# 将像素最大值小于255的图像归一化到255
return (img/np.max(img)*255).astype(np.uint8)
def hist_match_dark_prior(img, dark=False):
# 基于暗/亮通道的直方图规定化
result = img.copy()
for i in range(3):
result[:,:,i] = cv2.equalizeHist(result[:,:,i])
if dark==False:
dark_prior = np.min(result, axis=2)
else:
dark_prior = np.max(result, axis=2)
#image_hist(np.stack([dark_prior]*3, axis=2))
for j in range(3):
for i in range(3):
result[:,:,i] = hist_match(result[:,:,i], dark_prior)
result = normalize(result)
#image_hist(result)
return result
if __name__=="__main__":
img = cv2.imread("filename")
img = hist_match_all(img)
img = dehaze255(img)
cv2.imwrite("filename_write", img)
再放一个pytorch版的:
import torch
def torch_equalize(image):
"""Implements Equalize function from PIL using PyTorch ops based on:
https://github.com/tensorflow/tpu/blob/master/models/official/efficientnet/autoaugment.py#L352"""
def scale_channel(im, c):
"""Scale the data in the channel to implement equalize."""
im = im[:, :, c]
# Compute the histogram of the image channel.
histo = torch.histc(im, bins=256, min=0, max=255)#.type(torch.int32)
# For the purposes of computing the step, filter out the nonzeros.
nonzero_histo = torch.reshape(histo[histo != 0], [-1])
step = (torch.sum(nonzero_histo) - nonzero_histo[-1]) // 255
def build_lut(histo, step):
# Compute the cumulative sum, shifting by step // 2
# and then normalization by step.
lut = (torch.cumsum(histo, 0) + (step // 2)) // step
# Shift lut, prepending with 0.
lut = torch.cat([torch.zeros(1), lut[:-1]])
# Clip the counts to be in range. This is done
# in the C code for image.point.
return torch.clamp(lut, 0, 255)
# If step is zero, return the original image. Otherwise, build
# lut from the full histogram and step and then index from it.
if step == 0:
result = im
else:
# can't index using 2d index. Have to flatten and then reshape
result = torch.gather(build_lut(histo, step), 0, im.flatten().long())
result = result.reshape_as(im)
return result.type(torch.uint8)
# Assumes RGB for now. Scales each channel independently
# and then stacks the result.
image = image.type(torch.float)
s1 = scale_channel(image, 0)
s2 = scale_channel(image, 1)
s3 = scale_channel(image, 2)
image = torch.stack([s1, s2, s3], 2)
return image
def find_nearest_above(my_array, target):
diff = my_array - target
mask = diff <= -1
# We need to mask the negative differences
# since we are looking for values above
if torch.all(mask):
c = torch.abs(diff).argmin()
return c # returns min index of the nearest if target is greater than any value
masked_diff = diff.clone()
masked_diff[mask] = 9999
return masked_diff.argmin()
def hist_match(source, template):
s = source.view(-1)
t = template.view(-1)
s_values, bin_idx, s_counts = torch.unique(s, return_inverse=True, return_counts=True)
t_values, t_counts = torch.unique(t, return_counts=True)
s_quantities = torch.cumsum(s_counts,0).type(torch.float)
t_quantities = torch.cumsum(t_counts,0).type(torch.float)
s_quantities = s_quantities/s_quantities[s_quantities.shape[0]-1]
t_quantities = t_quantities/t_quantities[t_quantities.shape[0]-1]
sour = (s_quantities * 255).type(torch.long)
temp = (t_quantities * 255).type(torch.long)
b = torch.zeros(sour.shape)
for i in range(sour.shape[0]):
b[i] = find_nearest_above(temp, sour[i])
s=b[bin_idx]
return s.view(source.shape)
def hist_match_dark_prior(img):
# input: img[h, w, c]
# output:res[h, w, c]
result = img.clone()
result = torch_equalize(result)
dark_prior,_ = torch.min(result, axis=2)
for i in range(3):
result[:,:,i] = hist_match(result[:,:,i], dark_prior)
return result
if __name__=='__main__':
from PIL import Image
import numpy as np
im=Image.open("Night-schene-03.jpg")
img=torch.from_numpy(np.array(im))
img1=hist_match_dark_prior(img).numpy()
im1=Image.fromarray(img1)
im1.save('out.png')
展开阅读
#include<opencv2/opencv.hpp>
#include<iostream>
#include<iomanip>
#include<string>
#include<vector>
#include<ctime>
#include<algorithm>
using namespace std;
using namespace cv;
string type2str(int type) {
string r;
uchar depth = type & CV_MAT_DEPTH_MASK;
uchar chans = 1 + (type >> CV_CN_SHIFT);
switch (depth) {
case CV_8U: r = "8U"; break;
case CV_8S: r = "8S"; break;
case CV_16U: r = "16U"; break;
case CV_16S: r = "16S"; break;
case CV_32S: r = "32S"; break;
case CV_32F: r = "32F"; break;
case CV_64F: r = "64F"; break;
default: r = "User"; break;
}
r += "C";
r += (chans + '0');
return r;
}
bool isU(int type) {
string r;
uchar depth = type & CV_MAT_DEPTH_MASK;
uchar chans = 1 + (type >> CV_CN_SHIFT);
switch (depth) {
case CV_8U: return true; break;
case CV_8S: return false; break;
case CV_16U: return true; break;
case CV_16S: return false; break;
case CV_32S: return false; break;
case CV_32F: return false; break;
case CV_64F: return false; break;
default: return false; break;
}
}
bool isF(int type) {
string r;
uchar depth = type & CV_MAT_DEPTH_MASK;
uchar chans = 1 + (type >> CV_CN_SHIFT);
switch (depth) {
case CV_8U: return false; break;
case CV_8S: return false; break;
case CV_16U: return false; break;
case CV_16S: return false; break;
case CV_32S: return false; break;
case CV_32F: return true; break;
case CV_64F: return true; break;
default: return false; break;
}
}
Mat U2F(Mat src)
{
// convert unsigned char (0-255) image to float (0-1) image
Mat dst;
src.convertTo(dst, CV_32F, 1 / 255.0);
return dst;
}
Mat F2U(Mat src)
{
// convert float (0-1) image to unsigned char (0-255) image
Mat dst = src.clone()*255;
src.convertTo(dst, CV_8U, 1);
return dst;
}
void print_size(Mat src)
{
// print height width channels
int size_h = src.size[0];
int size_w = src.size[1];
int size_z = src.channels();
cout << type2str(src.type()) << endl;
cout << "h: " << size_h << " w: " << size_w << " z: " << size_z << endl;
return;
}
double min(Mat Y)
{
// return min element in an image
double min, max;
minMaxIdx(Y, &min, &max);
return min;
}
double max(Mat Y)
{
// return max element in an image
double min, max;
minMaxIdx(Y, &min, &max);
return max;
}
void arg_min(Mat Y, int idx[2])
{
minMaxIdx(Y, 0, 0, idx, 0);
return;
}
void arg_max(Mat Y, int idx[2])
{
minMaxIdx(Y, 0, 0, 0, idx);
return;
}
Mat reduce_min(Mat in)
{
Mat src = in.clone();
// reduce min of an image over the third dimension
int size_h = src.size[0];
int size_w = src.size[1];
int size_z = src.channels();
vector<Mat> channels(size_z);
split(src, channels);
Mat minmat;
if (isF(src.type()))
{
minmat = Mat(size_h, size_w, CV_32F, Scalar(FLT_MAX));
}
else if (isU(src.type()))
{
minmat = Mat(size_h, size_w, CV_8U, Scalar(255));
}
for (int z = 0; z < size_z; ++z)
{
min(channels[z], minmat, minmat);
}
return minmat;
}
Mat reduce_max(Mat in)
{
Mat src = in.clone();
// reduce max of an image over the third dimension
int size_h = src.size[0];
int size_w = src.size[1];
int size_z = src.channels();
vector<Mat> channels(size_z);
split(src, channels);
Mat maxmat;
if (isF(src.type()))
{
maxmat = Mat(size_h, size_w, CV_32F, Scalar(FLT_MIN));
}
else if (isU(src.type()))
{
maxmat = Mat(size_h, size_w, CV_8U, Scalar(0));
}
for (int z = 0; z < size_z; ++z)
{
max(channels[z], maxmat, maxmat);
}
return maxmat;
}
Mat reduce_mean(Mat in)
{
Mat src = in.clone();
if (!isF(src.type()))
{
src = U2F(src);
}
// reduce mean of an image over the third dimension
int size_h = src.size[0];
int size_w = src.size[1];
int size_z = src.channels();
vector<Mat> channels(size_z);
split(src, channels);
Mat summat(size_h, size_w, CV_32F, Scalar(0));
for (int z = 0; z < size_z; ++z)
{
summat = summat + channels[z];
}
return summat/size_z;
}
Mat cumsum(Mat src)
{
Mat dst = src.clone();
if (!isF(dst.type()))
{
dst = U2F(dst);
}
// cumsum of Mat array
int size_h = dst.size[0];
int size_w = dst.size[1];
for (int i = 1; i < size_h; ++i)
{
dst.at<float>(i) += dst.at<float>(i - 1);
}
return dst;
}
template<typename T>
vector<float> cumsum_vec(vector<T> src)
{
vector<float> dst(src.size(), 0);
for (int i = 0; i < src.size(); ++i)
{
dst[i] = (float)src[i];
}
for (int i = 1; i < src.size(); ++i)
{
dst[i] += dst[i - 1];
}
return dst;
}
Mat myCalcHist(Mat V1, int bins = 100)
{
Mat ht;
int channels[] = { 0 };
int histSize[] = { bins };
float granges[] = { 0, 255 };
const float* ranges[] = { granges };
calcHist(&V1, 1, channels, Mat(), ht, 1, histSize, ranges, true, false);
return ht;
}
bool all(Mat src)
{
int size_h = src.size[0];
int size_w = src.size[1];
int size_z = src.channels();
bool result = true;
for (int i = 0; i < size_h; i++)
{
for (int j = 0; j < size_w; j++)
{
for (int z = 0; z < size_z; z++)
{
if (src.at<uchar>(i,j,z) == 0)
result = false;
}
}
}
return result;
}
template<typename T>
vector<T> abs(vector<T> src)
{
vector<T> dst(src.begin(), src.end());
for (int i = 0; i < src.size(); i++)
{
dst[i] = abs(src[i]);
}
return dst;
}
bool all(vector<bool> mask)
{
bool result = true;
for (int i = 0; i < mask.size(); i++)
{
if (!mask[i])
result = false;
}
return result;
}
Mat masked_array(Mat src, Mat mask, int padd=255)
{
int size_h = src.size[0];
int size_w = src.size[1];
int size_z = src.channels();
Mat result = src.clone();
for (int i = 0; i < size_h; i++)
{
for (int j = 0; j < size_w; j++)
{
for (int z = 0; z < size_z; z++)
{
if (!(mask.at<uchar>(i, j, z) == 0))
{
result.at<int>(i, j, z) = padd;
}
else
{
result.at<int>(i, j, z) = src.at<int>(i, j, z);
}
}
}
}
return result;
}
template<typename T>
vector<T> masked_array(vector<T> src, vector<bool> mask, T padd)
{
vector<T> result(src.size(), padd);
for (int i = 0; i < src.size(); i++)
{
if (!(mask[i] == false))
{
result[i] = padd;
}
else
{
result[i] = src[i];
}
}
return result;
}
template <typename T, typename Compare>
std::vector<std::size_t> sort_permutation(
const std::vector<T>& vec,
Compare& compare)
{
std::vector<std::size_t> p(vec.size());
std::iota(p.begin(), p.end(), 0);
std::sort(p.begin(), p.end(),
[&](std::size_t i, std::size_t j){ return compare(vec[i], vec[j]); });
return p;
}
template <typename T>
std::vector<T> apply_permutation(
const std::vector<T>& vec,
const std::vector<std::size_t>& p)
{
std::vector<T> sorted_vec(vec.size());
std::transform(p.begin(), p.end(), sorted_vec.begin(),
[&](std::size_t i){ return vec[i]; });
return sorted_vec;
}
void unique(vector<int> src, vector<int>& uni, vector<int>& idx, vector<int>& count)
{
idx = vector<int>(src.size(), 0);
int hash[256] = { 0 };
for (int i = 0; i < src.size(); i++)
{
hash[src[i]]++;
}
int k = 0;
int new_idx[256];
for (int i = 0; i < 256; i++)
{
if (hash[i] != 0)
{
uni.push_back(i);
count.push_back(hash[i]);
new_idx[i] = k;
k++;
}
}
for (int i = 0; i < src.size(); i++)
{
idx[i] = new_idx[src[i]];
}
return;
}
template<typename T>
void print(std::vector <T> const &a) {
std::cout << "The vector elements are : ";
for (int i = 0; i < a.size(); i++)
std::cout << a.at(i) << ' ';
std::cout << "\n" << endl;
}
template<typename T>
std::vector<T> slice_vec(std::vector<T> const &v, int m, int n)
{
auto first = v.cbegin() + m;
auto last = v.cbegin() + n + 1;
std::vector<T> vec(first, last);
return vec;
}
Mat zmMinFilterGray(Mat src, int r = 7)
{
Mat dst;
erode(src, dst, getStructuringElement(MORPH_RECT, Size(2 * r + 1, 2 * r + 1)));
//imshow("erode", dst);
waitKey();
return dst;
}
Mat guidedfilter(Mat I, Mat p, int r, float eps)
{
Mat m_I, m_p, m_Ip, m_II, m_a, m_b;
boxFilter(I, m_I, -1, { r, r });
boxFilter(p, m_p, -1, { r, r });
boxFilter(I.mul(p), m_Ip, -1, { r, r });
Mat cov_Ip = m_Ip - m_I.mul(m_p);
boxFilter(I.mul(I), m_II, -1, { r, r });
Mat var_I = m_II - m_I.mul(m_I);
Mat a = cov_Ip / (var_I + eps);
Mat b = m_p - a.mul(m_I);
boxFilter(a, m_a, -1, { r, r });
boxFilter(b, m_b, -1, { r, r });
return m_a.mul(I) + m_b;
}
int getV1(Mat m, int r, float eps, float w, float maxV1, Mat &V1, float& A)
{
Mat ht;
V1 = reduce_min(m);
//imshow("dark", V1);
waitKey();
V1 = guidedfilter(V1, zmMinFilterGray(V1, 7), r, eps);
//imshow("filter", V1);
waitKey();
int bins = 100;
int channels[] = { 0};
int histSize[] = { bins };
float granges[] = { 0, 1 };
const float* ranges[] = { granges };
calcHist(&V1, 1, channels, Mat(), ht, 1, histSize, ranges, true, false);
ht.convertTo(ht, CV_32F, V1.size[0] * V1.size[1]);
Mat d = cumsum(ht);
int lmax = bins - 1;
for (; lmax > 0; lmax--)
{
if (d.at<float>(lmax) < 0.999)
break;
}
Mat avg = reduce_mean(m);
int size_h = m.size[0];
int size_w = m.size[1];
//cout << "lmax" << lmax << endl;
A = -1; //negative inf
for (int i = 0; i < size_h; ++i)
{
for (int j = 0; j < size_w; ++j)
{
if (V1.at<float>(i, j) >= lmax / bins)
if (avg.at<float>(i, j)>A)
A = avg.at<float>(i, j);
}
}
min(V1*w, maxV1, V1);
return 0;
}
Mat deHaze(Mat m, int r = 81, float eps = 0.001, float w = 0.95, float maxV1 = 0.80)
{
m = U2F(m);
int size_h = m.size[0];
int size_w = m.size[1];
int size_z = m.channels();
Mat Y = m.clone();
Mat V1;
float A;
getV1(m, r, eps, w, maxV1, V1, A);
//imshow("V1", V1);
waitKey(0);
vector<Mat> channels_Y(size_z);
vector<Mat> channels_m(size_z);
//split(Y, channels_Y);
split(m, channels_m);
//cout << "A" << A << endl;
for (int k = 0; k < size_z; ++k)
{
channels_Y[k] = (channels_m[k] - V1) / (1 - V1 / A);
}
merge(channels_Y, Y);
max(Y, 0, Y); //clip
min(Y, 1, Y); //clip
Y = 255 * Y;
Y = F2U(Y);
return Y;
}
void normalize(Mat &src)
{
src.convertTo(src, CV_32F, 1.0/max(src));
src.convertTo(src, CV_8U, 255);
}
template<typename T>
int find_nearest_above(vector<T> my_array, T target)
{
vector<T> diff(my_array.size(), 0);
for (int i = 0; i < my_array.size(); i++)
{
diff[i] = my_array[i] - target;
}
vector<bool> mask(my_array.size(), false);
for (int i = 0; i < diff.size(); i++)
{
mask[i] = diff[i]<=-1;
}
if (all(mask))
{
vector<T> abs_diff = abs(diff);
vector<T>::iterator iter = min_element(abs_diff.begin(), abs_diff.end());
int c = iter - abs_diff.begin();
return c;
}
vector<T> masked_diff = masked_array(diff, mask, 255);
vector<T>::iterator iter = min_element(masked_diff.begin(), masked_diff.end());
int c = iter - masked_diff.begin();
return c;
}
Mat hist_match(Mat original, Mat specified)
{
int ori_h = original.size[0];
int ori_w = original.size[1];
int sp_h = specified.size[0];
int sp_w = specified.size[1];
vector<int> ori_array(ori_h*ori_w, 0), sp_array(sp_h*sp_w,0);
for (int i = 0; i < ori_h; i++)
{
for (int j = 0; j < ori_w; j++)
{
ori_array[i*ori_w + j] = original.at<uchar>(i, j);
}
}
for (int i = 0; i < sp_h; i++)
{
for (int j = 0; j < sp_w; j++)
{
sp_array[i*sp_w + j] = specified.at<uchar>(i, j);
}
}
vector<int> s_values, bin_idx, s_counts, t_values, t_counts;
unique(ori_array, s_values, bin_idx, s_counts);
unique(sp_array, t_values, vector<int>(), t_counts);
/*print(s_values);
vector<int> sliced = slice_vec(bin_idx, 0, 10);
print(sliced);
print(s_counts);*/
vector<float> s_quantities = cumsum_vec(s_counts);
vector<float> t_quantities = cumsum_vec(t_counts);
for (int i = 0; i < s_quantities.size(); i++)
{
s_quantities[i] /= s_quantities[s_quantities.size()-1];
}
for (int i = 0; i < t_quantities.size(); i++)
{
t_quantities[i] /= t_quantities[t_quantities.size() - 1];
}
vector<int> sour(s_quantities.size(), 0), temp(t_quantities.size(), 0);
for (int i = 0; i < s_quantities.size(); i++)
{
sour[i] = (int)(s_quantities[i] * 255);
}
for (int i = 0; i < t_quantities.size(); i++)
{
temp[i] = (int)(t_quantities[i] * 255);
}
vector<int> b;
for (int i = 0; i < sour.size(); i++)
{
b.push_back(find_nearest_above(temp, sour[i]));
}
/*cout << "b[i]" << endl;
for (int i = 0; i < b.size(); i++)
{
cout << b[i] << endl;
}*/
Mat dst = original.clone();
int k = 0;
for (int i = 0; i < ori_h; i++)
{
for (int j = 0; j < ori_w; j++)
{
dst.at<uchar>(i, j) = b[bin_idx[k]];
k++;
}
}
return dst;
}
Mat bright_hist_match(Mat src)
{
if (!isU(src.type()))
{
src = F2U(src);
}
int size_h = src.size[0];
int size_w = src.size[1];
int size_z = src.channels();
Mat dst;
Mat equalized;
vector<Mat> channels_src(size_z);
vector<Mat> channels_tmp(size_z);
vector<Mat> channels_dst(size_z);
split(src, channels_src);
for (int i = 0; i < size_z; i++)
{
equalizeHist(channels_src[i], channels_tmp[i]);
}
merge(channels_tmp, equalized);
Mat bright_prior = reduce_max(equalized);
for (int i = 0; i < size_z; i++)
{
channels_dst[i] = hist_match(channels_tmp[i], bright_prior);
}
merge(channels_dst, dst);
print_size(dst);
normalize(dst);
return dst;
}
int main()
{
clock_t start, end;
Mat img = imread("100.png");
start = clock();
img = deHaze(img);
end = clock();
double cost = (double)(end - start)/CLOCKS_PER_SEC;
//cout.setf(ios::fixed);
cout << "使用时间:" << cost << "s" << endl;
cout << "分辨率:" << img.size[1] << "x" << img.size[0] << endl;
imshow("fuck",img);
waitKey(0);
}
展开阅读
工具1:在MinGW官网上根据教程下载mingw-get,在MinGW Installation Manager中选中mingw-developer-toolkit-bin,mingw32-base-bin,和mingw32-gcc-g++-bin,并安装到一个没有中文或者空格的目录下
工具2:下载git for windows并安装到一个没有中文或者空格的目录下
在Makefile文件下打开Git Bash(这个bash下可以支持常用的linux命令),输入mingw32-make mingw编译,输入mingw32-make mingw install安装
展开阅读
设有n 种不同面值的硬币,每个硬币的面值存于数组$T[1:n]$中。现在用这些硬币来找钱。各种硬币使用的个数不限。设计一个动态规划算法以计算找出钱m 时,所用的硬币的最小个数C。
def change_money(T,m):
T.sort() # 保证面额单调递增
n=len(T)
C=[[0]*(m+1) for i in range(n)] # j=m时找的钱为m,因此初始化到m+1大小
for j in range(m+1):
if j%T[0]==0:
C[0][j] = j//T[0] # 边界条件,只用最小面额的硬币
else:
C[0][j] = float('inf') # 最小面额硬币无法找钱时,不可能找钱
for i in range(1,n):
for j in range(1,m+1):
plans = []
for k in range(j//T[i]+1): # k 是要用新的面额硬币的个数
plans.append(C[i-1][j-k*T[i]]+k) # 去掉用大额硬币的金额,剩下的金额找钱
C[i][j]=min(plans) # 在不同k值的方案中选最优
return C[n-1][m]
设计一个动态规划算法从n 个数构成的数列中找出最长单调递增子序列。
def LCS(X,Y):
# 使用最长公共子序列算法求解
n = len(X)
m = len(Y)
C=[[0]*m for i in range(n)]
B=[['']*n for i in range(n)]
for i in range(1,n):
for j in range(1,m):
if X[i]==Y[j]:
C[i][j]=C[i-1][j-1]+1
B[i][j]="ul"
elif C[i-1][j]>=C[i][j-1]:
C[i][j]=C[i-1][j]
B[i][j]="up"
else:
C[i][j]=C[i][j-1]
B[i][j]="left"
return B,C
def print_subsequence(B,X,i,j,ans):
if i==0 or j==0:
return
if B[i][j]=="ul":
print_subsequence(B,X,i-1,j-1,ans)
ans.append(X[i])
elif B[i][j]=="up":
print_subsequence(B,X,i-1,j,ans)
else:
print_subsequence(B,X,i,j-1,ans)
def longest_subsequence(X):
# X[0]恒为0,不表示序列元素
B,C=LCS(X,[0]+sorted(X[1:]))
ans=[]
print_subsequence(B,X,len(X)-1,len(X)-1,ans)
return ans
展开阅读
以下代码使用了半正矢公式:
$\text{haversine}(\varphi_1,\theta_1,\varphi_2,\theta_2)=2R\arctan \sqrt\frac{a}{1-a}, $
其中 $a=\sin^2\frac{\Delta\varphi}{2} +\cos\varphi_1\cos\varphi_2\sin^2\frac{\Delta \theta}{2}, \Delta \varphi=\varphi_2-\varphi_1, \Delta\theta=\theta_2-\theta_1$ ,R是地球半径,以上公式使用弧度,因此代码中进行了角度转弧度运算。
import qualified Data.List.Split as Split
import Text.Read
import Data.List
type LatLong = (Double, Double)
toRadians :: Double -> Double
toRadians degrees = degrees * pi / 180
latLongToRads :: LatLong -> (Double, Double)
latLongToRads (lat,long) = (rlat, rlong)
where rlat = toRadians lat
rlong = toRadians long
haversine :: LatLong -> LatLong -> Double
haversine coords1 coords2 = earthRadius * c
where (rlat1, rlong1) = latLongToRads coords1
(rlat2, rlong2) = latLongToRads coords2
dlat = rlat2 - rlat1
dlong = rlong2 - rlong1
a = (sin (dlat/2))^2 + cos rlat1 * cos rlat2 * (sin (dlong/2))^2
c = 2 * atan2 (sqrt a) (sqrt (1-a))
earthRadius = 6367.5
printDistance :: Maybe Double -> IO()
printDistance Nothing = putStrLn "Error, invalid LatLong entered"
printDistance (Just distance) = putStrLn (show distance ++ " km")
contextExtract :: Applicative f => (f a1, f a2) -> f (a1, a2)
contextExtract d = pure (,) <*> fst d <*> snd d
string2LatLong :: String -> Maybe LatLong
string2LatLong s = contextExtract (latMaybe, longMaybe)
where arr = Split.splitOn "," s
indexedArr = zip [1..] arr
lat = lookup 1 indexedArr
long = lookup 2 indexedArr
latMaybe = (lat >>= readMaybe)::(Maybe Double)
longMaybe = (long >>= readMaybe)::(Maybe Double)
main :: IO()
main = do
putStrLn "Enter the starting LatLong(degrees,eg: 33.82,-84.11):"
startingInput <- getLine
let startingLatLong = string2LatLong startingInput
putStrLn "Enter the destination LatLong(degrees,eg: 33.82,-84.11):"
destInput <- getLine
let destLatLong = string2LatLong destInput
let distance = haversine <$> startingLatLong <*> destLatLong
printDistance distance
展开阅读
使用类型Robot来模拟class Robot,使用State来模拟Robot class的属性值,使用类型Robot -> a来模拟输出类型为a的getter方法,使用Robot->a->Robot或(Robot, Robot )->a->(Robot, Robot)类型的函数模拟setter方法或改变多个对象状态的方法。其中gentleGiant killerRobot fastRobot 和slowRobot 是4个Robot对象实例,robotList保存这4个对象
以下是源代码:
{-# LANGUAGE ImpredicativeTypes #-}
-- State是Robot类的所有属性
type State = (String, Int, Int)
-- Robot 类
type Robot = forall t. ((State -> t) -> t)
-- Robot类的构造方法
robot :: State-> Robot
robot s f = f s
name :: State -> String
name (n,x,y) = n
attack :: State -> Int
attack (x,a,y) = a
hp :: State -> Int
hp (x,y,hp) = hp
-- name getter
getName :: Robot -> String
getName r = r name
-- attack getter
getAttack :: Robot -> Int
getAttack r = r attack
-- HP getter
getHP :: Robot -> Int
getHP r = r hp
-- name setter
setName :: Robot -> String -> Robot
setName aRobot newName = aRobot (\(n,a,h) -> robot (newName,a,h))
-- attack setter
setAttack :: Robot -> Int -> Robot
setAttack aRobot newAttack = aRobot (\(n,a,h) -> robot (n,newAttack,h))
-- HP setter
setHP :: Robot -> Int -> Robot
setHP aRobot newHP = aRobot (\(n,a,h) -> robot (n,a,newHP))
-- print方法
printRobot aRobot = aRobot (\(n,a,h) -> n ++ " attack:" ++ (show a) ++ " hp:" ++ (show h))
-- 对象的被打方法 aRobot被打,attackDamage是敌人对他的伤害
-- 相当于 aRobot.damage(attackDamage);
damage :: Robot -> Int -> Robot
damage aRobot attackDamage = aRobot (\(n, a, h) -> robot (n, a, h - attackDamage))
-- defender的被打方法,被aRobot打
-- 相当于defender.fight(aRobot);
fight :: Robot -> Robot -> Robot
fight aRobot defender = damage defender attack
where attack = if (getHP aRobot) > 10
then (getAttack aRobot)
else 0
-- 这些实例都是Robot类的
gentleGiant, killerRobot, fastRobot, slowRobot :: Robot
gentleGiant = robot ("Mr. Friendly", 10, 300)
killerRobot = robot ("Kill3r",25,200)
fastRobot = robot ("speedy", 15, 40)
slowRobot = robot ("slowpoke",20,30)
-- Robot列表
robotList :: [Robot]
robotList = [gentleGiant, killerRobot, slowRobot]
-- 获取列表中所有对象的HP
getHPList :: [Robot] -> [Int]
getHPList = map getHP
-- 两个对象对打,返回这两个对象
-- 相当于oneRoundFight(&r1, &r2);
oneRoundFight :: (Robot, Robot) -> (Robot, Robot)
oneRoundFight (r1, r2) = (fight r2 r1, fight r1 r2)
-- 两个对象对打,返回这两个对象
-- 相当于threeRoundFight(&r1, &r2);
threeRoundFight :: (Robot, Robot) -> (Robot, Robot)
threeRoundFight (r1, r2) = if (getHP s1) > (getHP s2) then (s1,s2) else (s2,s1)
where (s1, s2) = oneRoundFight (oneRoundFight (oneRoundFight (r1, r2)))
main :: IO()
main = do let (winner, loser) = threeRoundFight (gentleGiant, killerRobot)
print (printRobot winner)
print (printRobot loser)
type Name = String
type Attack = Int
type HP = Int
data Robot = Robot {
name :: Name,
attack :: Attack,
hp :: HP }
-- name setter
setName :: Robot -> Name -> Robot
setName r newName = r { name = newName}
-- attack setter
setAttack :: Robot -> Attack -> Robot
setAttack r newAttack = r { attack=newAttack}
-- HP setter
setHP :: Robot -> HP -> Robot
setHP r newHP = r { hp= newHP}
-- print方法
printRobot r = name r ++ " attack:" ++ (show $ attack r) ++ " hp:" ++ (show $ hp r)
damage r attackDamage = setHP r $ hp r - attackDamage
fight aRobot defender = damage defender attackDamage
where attackDamage = if (hp aRobot) > 10
then (attack aRobot)
else 0
getHPList = map hp
oneRoundFight (r1, r2) = (fight r2 r1, fight r1 r2)
nRoundFight 1 (r1, r2) = oneRoundFight (r1, r2)
nRoundFight n (r1, r2) = oneRoundFight $ nRoundFight (n-1) (r1, r2)
aoeFight aRobot rList = map (fight aRobot) rList
-- 这些实例都是Robot类的
gentleGiant, killerRobot, fastRobot, slowRobot :: Robot
gentleGiant = Robot {name="Mr. Friendly", attack=10, hp=300}
killerRobot = Robot {name="Kill3r",attack=25,hp=200}
fastRobot = Robot {name="speedy", attack=15, hp=40}
slowRobot = Robot {name="slowpoke",attack=20,hp=30}
-- Robot列表
robotList :: [Robot]
robotList = [gentleGiant, killerRobot, slowRobot]
main :: IO()
main = do let (r1,r2) = nRoundFight 10 (gentleGiant, killerRobot)
print $printRobot r1
print $printRobot r2
print $getHPList robotList
let newList = aoeFight fastRobot robotList
print $getHPList newList
Haskell也可以使用Type Families实现函数类型多态
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE TypeFamilies #-}
class F a where
type Out a :: *
f :: a -> Out a
instance F String where
type Out String = String
f = show . length
instance F Int where
type Out Int = String
f = show
instance F Float where
type Out Float = Float
f = id