引言
欢迎关注我的公众号 “不要葱姜蒜的小屋”~~~
自遥远的古代开始,人们就没有放弃对夜空的探索。一直以来,我都想做一张星轨图。是那种自己的,不是用的别人的软件来制作,也不是调包制作。虽然调包和用别人现成的软件效果会更好,但就是在一些问题上,不想妥协,于是到了这个时候,我才可以说:‘我可以做了~’。
我的思路有两种。
一种是:图像融合。大致思路就是两张图片的每个像素点的三个rgb值乘以对应的权重值,然后相加。这种思路的弊端是:一是会出现像素值相加超过255阈值,造成的后果就是过曝。二是如果两张图片在拍摄的时候,相机发生了抖动,那在融合的时候就会出现晕影。三是,因为要考虑程序的复用,所以融合的图像就选取两张融合,那融合多张图片的时候,融合的权重在每次融合之前需要重新计算。还有就是两张图片的分辨率需要相等。
另一种思路我叫它lighter:对比两张图像的每个像素点,取最亮的那个像素点作为融合后的图像对象像素点的值。这种也有一个缺点,就是在拍摄的时候也不可以抖动,不然也会有晕影。两张图片的分辨率也需要相等。
如果使用压缩手段强行将两张不同分辨率的图片,压缩到同一分辨率,那在融合或者是lighter的时候也会出现晕影。
这是目前遇到的问题吧,接下来展示以下代码
程序介绍
图像融合,这里传入的图像需要是矩阵形式
import cv2
import numpy as np
from tqdm import tqdm
import time
def merge(image1, image2, weight1, weight2):
can = np.zeros(image1.shape, dtype='uint8')
for x in tqdm(range(image1.shape[0])):
for y in range(image1.shape[1]):
can[x][y] = np.array(image1[x][y]) * weight1 + np.array(image2[x][y]) * weight2
return can
当然OpenCV也有相应的图像融合的算法,下图左边是我的算法,右边是OpenCV内置算法。
lighter,传入图像的地址就可以了
import cv2
import numpy as np
from tqdm import tqdm
import time
def lighter(image1, image2):
first_image_brg = cv2.imread(image1)
final_image_bgr = cv2.imread(image2)
can = np.zeros(first_image_brg.shape)
for x in tqdm(range(first_image_brg.shape[0])):
for y in range(first_image_brg.shape[1]):
if np.mean(first_image_brg[x][y]) < np.mean(final_image_bgr[x][y]):
can[x][y] = final_image_bgr[x][y]
else:
can[x][y] = first_image_brg[x][y]
return can
这个东西在我写完之后,我在pillow库找到了几乎和我思路一样的函数方法。
但是很明显,pillow库是用c语言写的,效率比我高,而且我还看不到它的源码。唉~。这是lighter执行后的效果,它会自动替换为较亮的元素。我试了下pillow库的lighter方法,得到的图像观感上没有差别。但无奈它是c语言写的,在本地么的源码看。
等过几天天晴了,就开始追着星星拍拍拍~