不会画线稿?PaddlePaddle让你秒变灵魂画手!
目录
线稿可以让空无一物的画纸产生正形负形,更能以长短虚实、疏密深淡、张弛得当之势自然勾勒物象之形、神、光、色、体积、质感等,不同造诣的画者能驾驭出不同的画面,难度之大深不可测,变化多端甚是神奇。
线描技法源远流长,可以追溯到我们中国画的白描,中国古代有许多白描大师,如顾恺之、李公麟等都为我国留下了文艺瑰宝。
但线稿的另一种意义是从某个图片转变而来,只有黑色线条,便于临摹,十分方便。
PaddleHub转换
由开发者Mr.郑先生_提供
【PaddleHub模型贡献】一行代码实现从彩色图提取素描线稿转换成PaddleHub让大家更方便的使用
一、效果展示
图片效果






视频效果
原始视频链接:
https://player.bilibili.com/player.html?aid=373068021&bvid=BV14Z4y1g7uG&cid=264240737&page=1
<p>原视频</p> </div> <p/> <p>将视频内容转换为线稿:<br/> <a href="https://player.bilibili.com/player.html?aid=800614383&bvid=BV1zy4y1v7kQ&cid=262900480&page=1">https://player.bilibili.com/player.html?aid=800614383&bvid=BV1zy4y1v7kQ&cid=262900480&page=1</a></p> <p/> <div class="csdn-video-box"> <iframe id="Mf6aqBNi-1607561794813" src="https://player.bilibili.com/player.html?aid=800614383" allowfullscreen="true" data-mediaembed="bilibili"/> <p>
paddle带你将视频线稿化</p> </div> <p/> <h1><a id="_40"/>二、实现步骤</h1> <h2><a id="1_41"/>1.导入必要的库和模型</h2> <pre><code class="prism language-python"><span class="token keyword">import</span> cv2 <span class="token keyword">from</span> scipy <span class="token keyword">import</span> ndimage <span class="token keyword">from</span> model <span class="token keyword">import</span> Model <span class="token keyword">import</span> numpy <span class="token keyword">as</span> np <span class="token keyword">import</span> os os<span class="token punctuation">.</span>environ<span class="token punctuation">[</span><span class="token string">'CUDA_VISIBLE_DEVICES'</span><span class="token punctuation">]</span><span class="token operator">=</span><span class="token string">'0'</span> model <span class="token operator">=</span> Model<span class="token punctuation">(</span><span class="token string">'inference_model'</span><span class="token punctuation">,</span>use_gpu<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">,</span>use_mkldnn<span class="token operator">=</span><span class="token boolean">False</span><span class="token punctuation">,</span>combined<span class="token operator">=</span><span class="token boolean">False</span><span class="token punctuation">)</span> </code></pre> <h2><a id="2_52"/>2.处理视频</h2> <p>将视频按帧进行处理,并保存到images文件夹中。</p> <pre><code class="prism language-python"><span class="token keyword">def</span> <span class="token function">transform_video_to_image</span><span class="token punctuation">(</span>video_file_path<span class="token punctuation">,</span> img_path<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">''' 将视频中每一帧保存成图片 '''</span> video_capture <span class="token operator">=</span> cv2<span class="token punctuation">.</span>VideoCapture<span class="token punctuation">(</span>video_file_path<span class="token punctuation">)</span> fps <span class="token operator">=</span> video_capture<span class="token punctuation">.</span>get<span class="token punctuation">(</span>cv2<span class="token punctuation">.</span>CAP_PROP_FPS<span class="token punctuation">)</span> count <span class="token operator">=</span> <span class="token number">0</span> <span class="token keyword">while</span><span class="token punctuation">(</span><span class="token boolean">True</span><span class="token punctuation">)</span><span class="token punctuation">:</span> ret<span class="token punctuation">,</span> frame <span class="token operator">=</span> video_capture<span class="token punctuation">.</span>read<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">if</span> ret<span class="token punctuation">:</span> cv2<span class="token punctuation">.</span>imwrite<span class="token punctuation">(</span>img_path <span class="token operator">+</span> <span class="token string">'%d.jpg'</span> <span class="token operator">%</span> count<span class="token punctuation">,</span> frame<span class="token punctuation">)</span> count <span class="token operator">+=</span> <span class="token number">1</span> <span class="token keyword">else</span><span class="token punctuation">:</span> <span class="token keyword">break</span> video_capture<span class="token punctuation">.</span>release<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">'视频图片保存成功, 共有 %d 张'</span> <span class="token operator">%</span> count<span class="token punctuation">)</span> <span class="token keyword">return</span> fps fps <span class="token operator">=</span> transform_video_to_image<span class="token punctuation">(</span><span class="token string">'shipin.mp4'</span><span class="token punctuation">,</span> <span class="token string">'images/'</span><span class="token punctuation">)</span> </code></pre> <h2><a id="3_75"/>3.图片线稿化</h2> <pre><code class="prism language-python"><span class="token keyword">from</span> function <span class="token keyword">import</span> <span class="token operator">*</span> <span class="token keyword">for</span> home<span class="token punctuation">,</span> dirs<span class="token punctuation">,</span> files <span class="token keyword">in</span> os<span class="token punctuation">.</span>walk<span class="token punctuation">(</span><span class="token string">'images'</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">for</span> filename <span class="token keyword">in</span> files<span class="token punctuation">:</span> fullname <span class="token operator">=</span> os<span class="token punctuation">.</span>path<span class="token punctuation">.</span>join<span class="token punctuation">(</span>home<span class="token punctuation">,</span> filename<span class="token punctuation">)</span> from_mat <span class="token operator">=</span> cv2<span class="token punctuation">.</span>imread<span class="token punctuation">(</span>fullname<span class="token punctuation">)</span> width <span class="token operator">=</span> <span class="token builtin">float</span><span class="token punctuation">(</span>from_mat<span class="token punctuation">.</span>shape<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span> height <span class="token operator">=</span> <span class="token builtin">float</span><span class="token punctuation">(</span>from_mat<span class="token punctuation">.</span>shape<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span> new_width <span class="token operator">=</span> <span class="token number">0</span> new_height <span class="token operator">=</span> <span class="token number">0</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>width <span class="token operator">></span> height<span class="token punctuation">)</span><span class="token punctuation">:</span> from_mat <span class="token operator">=</span> cv2<span class="token punctuation">.</span>resize<span class="token punctuation">(</span>from_mat<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token number">512</span><span class="token punctuation">,</span> <span class="token builtin">int</span><span class="token punctuation">(</span><span class="token number">512</span> <span class="token operator">/</span> width <span class="token operator">*</span> height<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> interpolation<span class="token operator">=</span>cv2<span class="token punctuation">.</span>INTER_AREA<span class="token punctuation">)</span> new_width <span class="token operator">=</span> <span class="token number">512</span> new_height <span class="token operator">=</span> <span class="token builtin">int</span><span class="token punctuation">(</span><span class="token number">512</span> <span class="token operator">/</span> width <span class="token operator">*</span> height<span class="token punctuation">)</span> <span class="token keyword">else</span><span class="token punctuation">:</span> from_mat <span class="token operator">=</span> cv2<span class="token punctuation">.</span>resize<span class="token punctuation">(</span>from_mat<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token builtin">int</span><span class="token punctuation">(</span><span class="token number">512</span> <span class="token operator">/</span> height <span class="token operator">*</span> width<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">512</span><span class="token punctuation">)</span><span class="token punctuation">,</span> interpolation<span class="token operator">=</span>cv2<span class="token punctuation">.</span>INTER_AREA<span class="token punctuation">)</span> new_width <span class="token operator">=</span> <span class="token builtin">int</span><span class="token punctuation">(</span><span class="token number">512</span> <span class="token operator">/</span> height <span class="token operator">*</span> width<span class="token punctuation">)</span> new_height <span class="token operator">=</span> <span class="token number">512</span> from_mat <span class="token operator">=</span> from_mat<span class="token punctuation">.</span>transpose<span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span> light_map <span class="token operator">=</span> np<span class="token punctuation">.</span>zeros<span class="token punctuation">(</span>from_mat<span class="token punctuation">.</span>shape<span class="token punctuation">,</span> dtype<span class="token operator">=</span>np<span class="token punctuation">.</span><span class="token builtin">float</span><span class="token punctuation">)</span> <span class="token keyword">for</span> channel <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">:</span> light_map<span class="token punctuation">[</span>channel<span class="token punctuation">]</span> <span class="token operator">=</span> get_light_map_single<span class="token punctuation">(</span>from_mat<span class="token punctuation">[</span>channel<span class="token punctuation">]</span><span class="token punctuation">)</span> light_map <span class="token operator">=</span> normalize_pic<span class="token punctuation">(</span>light_map<span class="token punctuation">)</span> light_map <span class="token operator">=</span> resize_img_512_3d<span class="token punctuation">(</span>light_map<span class="token punctuation">)</span> light_map <span class="token operator">=</span> light_map<span class="token punctuation">.</span>astype<span class="token punctuation">(</span><span class="token string">'float32'</span><span class="token punctuation">)</span> line_mat <span class="token operator">=</span> model<span class="token punctuation">.</span>predict<span class="token punctuation">(</span>np<span class="token punctuation">.</span>expand_dims<span class="token punctuation">(</span>light_map<span class="token punctuation">,</span> axis<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">.</span>astype<span class="token punctuation">(</span><span class="token string">'float32'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 去除 batch 维度 (512, 512, 3)</span> line_mat <span class="token operator">=</span> line_mat<span class="token punctuation">.</span>transpose<span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token comment"># 裁剪 (512, 384, 3)</span> line_mat <span class="token operator">=</span> line_mat<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">:</span><span class="token builtin">int</span><span class="token punctuation">(</span>new_height<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">:</span><span class="token builtin">int</span><span class="token punctuation">(</span>new_width<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">:</span><span class="token punctuation">]</span> line_mat <span class="token operator">=</span> np<span class="token punctuation">.</span>amax<span class="token punctuation">(</span>line_mat<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token comment"># 降噪</span> show_active_img_and_save_denoise<span class="token punctuation">(</span>line_mat<span class="token punctuation">,</span> <span class="token string">'./output/'</span> <span class="token operator">+</span> filename<span class="token punctuation">)</span> <span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">'图片'</span> <span class="token operator">+</span> filename <span class="token operator">+</span> <span class="token string">'已经完成'</span><span class="token punctuation">)</span> <span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">'全部图片转换成功。'</span><span class="token punctuation">)</span> </code></pre> <h2><a id="4_119"/>4.合并视频</h2> <pre><code class="prism language-python"><span class="token keyword">def</span> <span class="token function">combine_image_to_video</span><span class="token punctuation">(</span>comb_path<span class="token punctuation">,</span> output_file_path<span class="token punctuation">,</span> fps<span class="token operator">=</span><span class="token number">30</span><span class="token punctuation">,</span> is_print<span class="token operator">=</span><span class="token boolean">False</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">''' 合并图像到视频 '''</span> fourcc <span class="token operator">=</span> cv2<span class="token punctuation">.</span>VideoWriter_fourcc<span class="token punctuation">(</span><span class="token operator">*</span><span class="token string">'MP4V'</span><span class="token punctuation">)</span> file_items <span class="token operator">=</span> os<span class="token punctuation">.</span>listdir<span class="token punctuation">(</span>comb_path<span class="token punctuation">)</span> file_len <span class="token operator">=</span> <span class="token builtin">len</span><span class="token punctuation">(</span>file_items<span class="token punctuation">)</span> <span class="token comment"># print(comb_path, file_items)</span> <span class="token keyword">if</span> file_len <span class="token operator">></span> <span class="token number">0</span> <span class="token punctuation">:</span> temp_img <span class="token operator">=</span> cv2<span class="token punctuation">.</span>imread<span class="token punctuation">(</span>os<span class="token punctuation">.</span>path<span class="token punctuation">.</span>join<span class="token punctuation">(</span>comb_path<span class="token punctuation">,</span> file_items<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span> img_height<span class="token punctuation">,</span> img_width <span class="token operator">=</span> temp_img<span class="token punctuation">.</span>shape<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> temp_img<span class="token punctuation">.</span>shape<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> out <span class="token operator">=</span> cv2<span class="token punctuation">.</span>VideoWriter<span class="token punctuation">(</span>output_file_path<span class="token punctuation">,</span> fourcc<span class="token punctuation">,</span> fps<span class="token punctuation">,</span> <span class="token punctuation">(</span>img_width<span class="token punctuation">,</span> img_height<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span>file_len<span class="token punctuation">)</span><span class="token punctuation">:</span> pic_name <span class="token operator">=</span> os<span class="token punctuation">.</span>path<span class="token punctuation">.</span>join<span class="token punctuation">(</span>comb_path<span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token operator">+</span><span class="token string">".jpg"</span><span class="token punctuation">)</span> <span class="token keyword">if</span> is_print<span class="token punctuation">:</span> <span class="token keyword">print</span><span class="token punctuation">(</span>i<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token string">'/'</span><span class="token punctuation">,</span> file_len<span class="token punctuation">,</span> <span class="token string">' '</span><span class="token punctuation">,</span> pic_name<span class="token punctuation">)</span> img <span class="token operator">=</span> cv2<span class="token punctuation">.</span>imread<span class="token punctuation">(</span>pic_name<span class="token punctuation">)</span> out<span class="token punctuation">.</span>write<span class="token punctuation">(</span>img<span class="token punctuation">)</span> out<span class="token punctuation">.</span>release<span class="token punctuation">(</span><span class="token punctuation">)</span> combine_image_to_video<span class="token punctuation">(</span><span class="token string">'output'</span><span class="token punctuation">,</span> <span class="token string">'work/mp4_analysis.mp4'</span><span class="token punctuation">,</span> fps<span class="token punctuation">)</span> </code></pre> <h2><a id="5_146"/>5.合并音频</h2> <pre><code class="prism language-python"><span class="token comment">#音频获取</span> <span class="token keyword">def</span> <span class="token function">getMusic</span><span class="token punctuation">(</span>video_name<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">""" 获取指定视频的音频 """</span> <span class="token comment"># 读取视频文件</span> video <span class="token operator">=</span> VideoFileClip<span class="token punctuation">(</span>video_name<span class="token punctuation">)</span> <span class="token comment"># 返回音频</span> <span class="token keyword">return</span> video<span class="token punctuation">.</span>audio <span class="token comment">#音频添加</span> <span class="token keyword">def</span> <span class="token function">addMusic</span><span class="token punctuation">(</span>video_name<span class="token punctuation">,</span> audio<span class="token punctuation">,</span>output_video<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">"""实现混流,给video_name添加音频"""</span> <span class="token comment"># 读取视频</span> video <span class="token operator">=</span> VideoFileClip<span class="token punctuation">(</span>video_name<span class="token punctuation">)</span> <span class="token comment"># 设置视频的音频</span> video <span class="token operator">=</span> video<span class="token punctuation">.</span>set_audio<span class="token punctuation">(</span>audio<span class="token punctuation">)</span> <span class="token comment"># 保存新的视频文件</span> video<span class="token punctuation">.</span>write_videofile<span class="token punctuation">(</span>output_video<span class="token punctuation">)</span> <span class="token keyword">from</span> moviepy<span class="token punctuation">.</span>editor <span class="token keyword">import</span> <span class="token operator">*</span> addMusic<span class="token punctuation">(</span><span class="token string">'work/mp4_analysis.mp4'</span><span class="token punctuation">,</span>getMusic<span class="token punctuation">(</span><span class="token string">'shipin.mp4'</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token string">'work/mp4_analysisnew.mp4'</span><span class="token punctuation">)</span> </code></pre> <h2><a id="PaddlePaddlehttpsaistudiobaiducomaistudioprojectdetail1301761_175"/><a href="https://aistudio.baidu.com/aistudio/projectdetail/1301761">点我进入项目-不会画线稿?
PaddlePaddle让你秒变灵魂画手!</a></h2>
本文同步分享在 博客“七年期限”(CSDN)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。