这里使用 Golang 中的GoCV
来实现图片的过渡效果以及生成 8 位颜色图片的中位切割算法
🚀 代码: Github
瞳孔过渡效果
Now suppose we wish to create a video transition such that the second video appears under the first video through a moving radius (like a clock hand), as in Fig. 2.23. Write a formula to use the correct pixels from the two videos to achieve this special effect for the red channel.
原图片
算法描述
这道题需要我们实现一个从切换的效果,从一张图片切换到另一张图片,并且从中间不断变大。
要实现这个效果,需要多张图片合成起来,而每一张图片中心的圆圈的半径应该是逐张变大。
对于过程中的每一张图片,生成的步骤如下:
- 找出图片的中点(
midX
,midY
) - 找出所要生成的圆圈的半径的大小
radius
- 生成一张新图片,对于其每一个像素点(
x
,y
)- 如果(
x
,y
)到(midX
,midY
)的距离小于radius
,那么填充第一张图片对应像素的颜色 - 如果(
x
,y
)到(midX
,midY
)的距离大于radius
,那么填充第二张图片对应像素的颜色
- 如果(
最后把过程中所有的图片合并起来,生成gif
或者avi
由于题目只是要求红色通道的颜色,因此生成的图片可以使用灰度图来表示。
因此,新图片中的像素可以用以下公式来表示
$$
\begin{cases}
color1(x, y)& \sqrt{(x-r)^2+(y-r)^2} > r\
color2(x, y)& \sqrt{(x-r)^2+(y-r)^2} < r
\end{cases}$$
程序实现
这里使用了GoCV
,使用go
语言调用了 OpenCV
库来实现程序功能。
如果你需要在你的电脑使用GoCV
,需要minGW
和CMake
环境编译安装OpenCV3.4.2
并设置好环境变量
1 | // ./main.go |
1 | // ./IrisImage/IrisImage.go |
实现效果
生成过程中的图片:
半径:25%
半径60%:
GIF效果图:
中位切分算法
For the color LUT problem, try out the median-cut algorithm on a sample image. Explain briefly why it is that this algorithm, carried out on an image of red apples, puts more color gradation in the resulting 24-bit color image where it is needed, among the reds.
算法描述
这道题需要使用median-cut
算法将原图简化为256种颜色的图片。
首先,我们要根据中值区分算法找出256种颜色:
- 将图片中所有的颜色放入一个数组里面
- 根据红色将所有的颜色划分为两个数量相等区域,前一个区域标记为0,后一个区域标记为1
- 对于两个区域,再次根据绿色将其划分为数量相等的两个区域
- 按照红、绿、蓝的顺序,重复上面两个步骤,直到所有颜色被划分为256个区域
- 对于每一个区域,取其R、G、B平均值作为其中心颜色
到此,我们就得到了一个Look-up table
,里面存放这这张图片最有代表性的256种颜色。
然后生成新的图片:
- 遍历原图片所有点,对于其每一个点:
- 在LUT中寻找与其RGB值的欧氏距离最小的值
- 填充到新图片对应的像素点中
程序实验
这里还是使用GoCV
来进行实验
对于Look-up table
的生成可以使用递归来实现,每次将颜色数组分割成两个部分,一直分割到第8次将结果的平均值放入table
中,那样就可以生成256种颜色的LUT
然后再对于图片每个像素计算到LUT
各个颜色的欧氏距离,取其最小距离的颜色,放入新图片中,那样就可以得到结果了。
1 | // ./main.go |
1 | // ./EightBit/EightBig.go |
效果分析
原图:
效果图
可以看出,一些细节部分的颜色缺失掉了。
我们可以输出他的LUT看一看
1 | [{0 4 121} {0 16 103} {5 11 122} {8 21 104} {1 8 136} {1 16 139} {7 13 139} {9 21 139} |
从上面可能看不出什么东西,因此我把LUT中三个通道的颜色提取出来并做了一个排序:
1 | R: |
然后我们得以下的图表
由于我们对R和G划分了3次,而对B只划分了两次,而且图中大多数的颜色都是红色和绿色,因此R和G的颜色的变化和范围也就更加地广。再加上图中红色是主体颜色,因此可以看出红色颜色的变化比起绿色和蓝色会更加地平滑,换句话来说,就是需要更多的红色来表示图片。
$$