抖音霓虹灯原理
抖音霓虹灯算法原理:
- 实时的光斑绘制,我们观察抖音霓虹的,你会发现所有的光斑都是圆形。所以,这里我们会使用cv2.circle()函数负责绘制霓虹圆形效果。
- 设计多幅素材图片,黑底上面有亮色的光斑,不同的图片中光斑的位置不同。
算法原理简单点翻译就是:加载视频,每间隔1帧在图像绘制光斑,一共定义4种光斑的位置,循环在视频中进行渲染。
实现4个图片霓虹灯效果
一般来说霓虹灯的效果都在视频的上下左右的边缘。为了让读者更加的通俗易懂一点,我们先来实现4个角的霓虹灯效果。
具体代码如下所示:
# 图片霓虹等效果
def img_neon_effetc(img, x, y, filenameSize):
cv2.circle(img, (x, y), 20, (114, 128, 250), -1)
cv2.circle(img, (x + 40, y - 40), 20, (153, 255, 102), -1)
cv2.circle(img, (x + 80, y + 40), 20, (15, 254, 123), -1)
cv2.circle(img, (x + 60, y), 20, (238, 169, 184), -1)
cv2.imwrite("55_" + filenameSize + ".jpg", img)
if __name__ == "__main__":
img = cv2.imread("55.jpg")
img1=img.copy()
height, width, n = img.shape
img_neon_effetc(img1, int(width * 0.1), int(height * 0.1), "1")
img1 = img.copy()
img_neon_effetc(img1, int(width * 0.1), int(height * 0.9), "2")
img1 = img.copy()
img_neon_effetc(img1, int(width * 0.9), int(height * 0.1), "3")
img1 = img.copy()
img_neon_effetc(img1, int(width * 0.9), int(height * 0.9), "4")
运行之后,会得到4个文件,效果如下:
实现视频霓虹灯效果
既然有了上述4个霓虹灯模板,相信读者应该知道要做什么了吧?没错,使用开始博文制作鬼影的函数cv2.addWeighted()函数进行图像加权和。
完整的霓虹灯代码如下所示:
#视频霓虹灯效果
def video_neon_effect(img, cnt):
if cnt == 0:
return img
height, width, n = img.shape
mask = {
1: cv2.imread("55_1.jpg"),
2: cv2.imread("55_2.jpg"),
3: cv2.imread("55_3.jpg"),
4: cv2.imread("55_4.jpg"),
}
mask[cnt] = cv2.resize(mask[cnt], (width, height), interpolation=cv2.INTER_CUBIC)
new_img = cv2.addWeighted(img, 0.7, mask[cnt], 0.3, 0)
return new_img
if __name__ == "__main__":
cap = cv2.VideoCapture("45.mp4")
fps = cap.get(cv2.CAP_PROP_FPS)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
i = 1
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
videoWriter = cv2.VideoWriter("output.avi", fourcc, fps, (width, height))
while (cap.isOpened()):
ret, frame = cap.read()
if ret:
frame = video_neon_effect(frame, i % 5)
cv2.imshow('video', frame)
videoWriter.write(frame)
i += 1
c = cv2.waitKey(1)
if c == 27:
break
else:
break
cap.release()
videoWriter.release()
cv2.destroyAllWindows()
运行之后,效果如下:
这里,你可以先将霓虹灯图像进行压缩,然后通过cv2.resize()函数将图片变更为视频的大小后,再进行加权和计算。实际的操作中,你还需要根据视频的帧数进行霓虹灯的设计操作,这里为了简便,小编只用了4张。
直接实现霓虹灯效果
上面我们是通过图片加权和进行霓虹灯效果的实现,但是是不是觉得跟抖音有点差距呢?这里,我们直接用代码实现霓虹灯,不用任何中间的操作,具体步骤如下:
- 随机生成一个霓虹灯图片,上面绘制了许多圆形。
- 记住这些圆形的位置信息,后面霓虹灯的变更更改其圆形颜色即可。
具体代码如下所示:
# 创建霓虹灯的圆
def create_neon_circle():
mask = np.zeros((576, 1024, 3), dtype=np.uint8)
circle_list = []
height, width, n = mask.shape
for i in range(0, width, 50):
for j in range(0, height, 50):
r = random.randint(0, 255)
g = random.randint(0, 255)
b = random.randint(0, 255)
x = i + random.randint(0, 90)
y = j + random.randint(0, 90)
cv2.circle(mask, (x, y), 20, (r, g, b), -1)
circle_list.append((x, y))
cv2.imwrite("55_1.jpg", mask)
return circle_list, mask
# 霓虹灯效果2
def video_neon_effect2(img, circle_list):
height, width, n = img.shape
mask = np.zeros((height, width, n), dtype=np.uint8)
for x, y in circle_list:
r = random.randint(0, 255)
g = random.randint(0, 255)
b = random.randint(0, 255)
cv2.circle(mask, (x, y), 20, (r, g, b), -1)
new_img = cv2.addWeighted(img, 0.7, mask, 0.3, 0)
return new_img,mask
if __name__ == "__main__":
cap = cv2.VideoCapture("45.mp4")
fps = cap.get(cv2.CAP_PROP_FPS)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
i = 1
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
videoWriter = cv2.VideoWriter("output.avi", fourcc, fps, (width, height))
circle_list, img = create_neon_circle()
while (cap.isOpened()):
ret, frame = cap.read()
if ret:
frame = cv2.addWeighted(frame, 0.7, img, 0.3, 0)
if i % 7 == 0:
frame ,img= video_neon_effect2(frame, circle_list)
cv2.imshow('video', frame)
videoWriter.write(frame)
i += 1
c = cv2.waitKey(1)
if c == 27:
break
else:
break
cap.release()
videoWriter.release()
cv2.destroyAllWindows()
运行之后,效果如下:
这里霓虹灯有些多,读者可以自己设置for循环的边界,比如只在屏幕顶端有霓虹灯效果,可以直接将For循环的高度缩小到顶部区域即可。如果觉得圆圈不好看,也可以设置绘制椭圆等。