抖音霓虹灯原理
抖音霓虹灯算法原理:
1.实时的光斑绘制,我们观察抖音霓虹的,你会发现所有的光斑都是圆形。所以,这里我们会使用cv2.circle()函数负责绘制霓虹圆形效果。
2.设计多幅素材图片,黑底上面有亮色的光斑,不同的图片中光斑的位置不同。
算法原理简单点翻译就是:加载视频,每间隔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张。
直接实现霓虹灯效果
上面我们是通过图片加权和进行霓虹灯效果的实现,但是是不是觉得跟抖音有点差距呢?这里,我们直接用代码实现霓虹灯,不用任何中间的操作,具体步骤如下:
1.随机生成一个霓虹灯图片,上面绘制了许多圆形。
2.记住这些圆形的位置信息,后面霓虹灯的变更更改其圆形颜色即可。
具体代码如下所示:
# 创建霓虹灯的圆 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循环的高度缩小到顶部区域即可。如果觉得圆圈不好看,也可以设置绘制椭圆等。