duangsuse::Echo
583 subscribers
4.12K photos
118 videos
579 files
6.13K links
import this:
美而不丑、明而不暗、短而不凡、长而不乱,扁平不宽,读而后码,行之天下,勿托地上天国。
异常勿吞,难过勿过,叹一真理。效率是很重要,盲目最是低效。
简明是可靠的先验,不是可靠的祭品。
知其变,守其恒,为天下式;穷其变,知不穷,得地上势。知变守恒却穷变知新,我认真理,我不认真。

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
#blog #dalao #dip https://bokjan.com/ #recommended 看今日 @metowolf 的新 follow,是一个优秀的华南理工在读大牛,他学的是软件工程,写过一些信息学、计算机图形学、图论、操作系统的东西

https://github.com/Bokjan?tab=repositories GitHub
#Machl #DIP https://github.com/zhiying8710/geetest_crack

发现了好东西。
= Geetest 是一种「验证不是机器人」(I'm not a robot, captcha)(验证码) 系统,基于「挑战」式检验
基于「生成歪七扭八的数据很容易,让机器恢复它们很难」的「事实?」设计

G2 是移动滑块的验证,用简单卷积识别应该可做
G3 第一部分是纯逻辑(不含「非精确的计算」)验证,直接可做
也可能是 G2 的滑块,通过率都是 99% (OpenCV) #CV
G4 是找七扭八扭又歪的汉字,需要 YOLO3 定位、CNN 识别汉字、CRNN 校验识别正确性
G5 也是一样,加个字典按照「语序」单词顺序就可以了
悲惨的起因,只是因为在 GitHub 上看到别人有用 Python+Pillow 写这个:

https://github.com/FerryYoungFan/SimpleTextMontage

虽然数学不好,对某些关系不那么扁平的数据处理也会非常吃力的 duangsuse 就头脑发热地想:

『这么简单的程序,我怎么可能不会写?我一定要写出来看看』

结果就杯具…… 😭 不过还是有一点收获,就是我学会了如何用 color average 插值写位图 scale 算法
虽然花了我至少 6 个小时的时间才完成到可以生成图片(本来应该只要一个小时,可是被 argparse 坑了…… 我不该一上来就填那么多参数),但感觉也还可以,而且我没有在任何关键问题上查资料,也没有看太多次 help
学习还是有效果的,毕竟我学会了这些 API:

Image.open(path)
Image.new(space, coord, fill)
Image#width, Image#height
Image#convert(space)
Image#getpixel(p) -> tuple
Image#setpixel(p, tuple)
ImageDraw.Draw(img: Image)
Draw#text(p, txt, font=, fill=)
ImageFont.load_path(path)
ImageFont.truetype(name, size=fntsz)
ImageFont.FreeTypeFont

当然一般来说为了性能(其实当然在 DIP 的时候算法是最重要的)都直接用 JVM 的 awt.BufferedImage 吧……

javap javax.imageio.ImageIO
javap java.awt.image.BufferedImage


我的 Gist 上有 Kotlin 字符画 ASCII Art 生成器的源码

看了 FerryYoungFan 的版本,10:52-11:27 花了半个多小时,好像不是提前写好了的,唉

算法上,除了 [xs[k:(k+2)] for k in (0,2,4)] 这种没见过(也不是不会写)都知道
不过设计上,没有扣像、 (keyColor, keyThres, keyRatio) 、自动渐变的背景色 (刚才我以为 count avgcolor 是拿来判断背景色的…) 和 xy padding (w- colPxs*m) /2
也没有加 textVsp 和 textHsp 文字间距,和图像边角的间距,我的版本写的更活一点,不过大概是没有太大意义的……

另外 (keyColor, keyThres), keyRatio 我还是会写的,之前的 Kotlin ASCII Art 就用到了 filter 色值的算法;只不过这个是按照 abs 符合要求色块数目来取舍是否生成文字

如果我使用高效的 Numpy/Pillow 内建函数,而不是我手动的 average 插值 scale 算法(Montage.clippy) 的话,就可以拿来处理视频(否则太慢了,处理不过来),实际上 B 站也有一个罗小黑战绩《晚安喵》的这种视频,有心人不妨试试重构。

#Python #tools #DIP
duangsuse::Echo
现在内存的问题解决了,这个图形处理算法可是有大问题……
https://github.com/duangsuse/extract-subtitles/blob/master/extract_subtitles.py#L55-L68
总结下,内存问题是用 chunked processing 解决的。
我简化了程序,梳理了下数据流,把合适的部分从靠 list 改成了用 generator(接着可以 hack 的地方就多了)
定义两个辅助 generator:

def chunked(n, xs):
while True:
try: #< must return when inner gen finished
first = next(xs)
except StopIteration: return
chunk = islice(xs, n)
yield chain((first,) , chunk)

def collect2(selector2, xs):
bs, cs = [], []
for x in xs:
b, c = selector2(x)
bs.append(b); cs.append(c)
return (bs, cs)


这段原程序就是之前会导致内存不够用的:
def solveFrameDifferences(self, cap: VideoCapture, crop: Rect, fold) -> Frame: #!generator

于是我移除了没损失信息量的对象,给它重构成 yield Frame(index, curr_frame, count) 的形式

接下来就是重构依赖它的依赖操作了,实际上只需要一个子程序来利用 collect2 来部分(按chunk)地执行计算,我这里直接加在原来依赖 list 版以上函数的操作里:
def ocrWithLocalMaxima(self, frames, on_new_subtitle) -> array:
然后,
    frame_list, frame_diffs = collect2(lambda it: (it, it.value), frames)
接下来的操作和以往无二,但再也不会内存不足了(只要你不关掉GC,相当于手动把视频切成 N 块再逐个操作,哈哈)。 🥳
self.onFrameList(frame_list)

但是,这种操作应该怎么运行(并且拿回,准确的说是「拼接」回结果)呢 🤔
刚才有说,直接贴代码:
processChunk = lambda it: self.ocrWithLocalMaxima(it, on_new_subtitle)
diff_array_parts = map(processChunk, chunked(self.chunk_size, frames))
diff_array = reduce(lambda a, b: concatenate(array([a, b])), diff_array_parts)


这就是我解决 opencv-python 处理内存不足问题的全部细节。 🙂 #Python #Learn #DIP #CV
#ai #dip 😋 老 照片 修复