Python 图像处理(一)PIL

2019-03-23 11:05栏目:ca888圈内

3. Model

10 x 10 的表格用长度为 100 的数组可周全映射游戏的个别「砖块」。

[ R, R, G, G, B, B, Y, Y, P, P, R, R, G, G, B, B, Y, Y, P, P, R, R, G, G, B, B, Y, Y, P, P, R, R, G, G, B, B, Y, Y, P, P, R, R, G, G, B, B, Y, Y, P, P, R, R, G, G, B, B, Y, Y, P, P, R, R, G, G, B, B, Y, Y, P, P, R, R, G, G, B, B, Y, Y, P, P, R, R, G, G, B, B, Y, Y, P, P, R, R, G, G, B, B, Y, Y, P, P ]

1
2
3
4
5
6
7
8
9
10
11
12
[
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P
]

卡宴 – 卡其色,G – 鲜青,B – 红色,Y – 伟青,P – 深橙。Model 的骨干职分是以下三个:

  • 扭转砖墙
  • 解决砖块 (生成砖块分值)
  • 做实砖墙
  • 扫除残砖 (生成奖励分值)

图像保存

img.save('d:/lena.jpg')

注:后面包车型大巴转折代码处理格局不一样,别的都是一模一样的,所以并未写代码

图像色彩处理


Android对图纸的处理,平日采纳的数据结构便是位图—Bitmap,它富含了一张图片的持有数据。整个图片都是由点阵和颜色值组成的,点阵正是一个含有像素的矩阵,每二个因素对应着图片的2个像素,颜色值—A君越GB,分别对应折射率、红、绿、蓝那多少个通道分量,它们一起决定了各种像素点呈现的颜料,对图片的情调解和处理理实际上就是对那一个像素点的大路分量做调整。

在色彩处理中,平时从八个角度来叙述一个图像。

  • 颜色:色彩的完全协助
  • 饱和度:颜色的纯度,从0(灰)到百分之百(饱和)来进展描述
  • 亮度:颜色的相对明暗程度

在android中,系统应用2个颜色矩阵—ColorMatrix,来处理图像的那么些色彩效果。Android中颜色矩阵是3个4x5的矩阵,它用来对图纸的色彩实行拍卖。而对于每一个像素点,都有2个颜色分量矩阵用来保存颜色的SportageGBA值,如下图所示:

图片 1

颜色矩阵A

图片 2

各类像素点的颜色分量矩阵C

在拍卖图像时,使用矩阵乘法运算AC来处理颜色分量矩阵,如下图所示:

图片 3

矩阵乘法运算

算算过程:
     R1 = a * R b * G c * B d * A e;
     G1 = f * R g * G h * B i * A j;
     B1 = k * R l * G m * B n * A o;
     A1 = p * R q * G r * B s * A t;

能够窥见,对于颜色矩阵A是按以下措施划分的:
    * 第②行的a b c d e值决定新的颜色值中的Rubicon分量—浅灰
    * 第3行的f g h i j值决定新的颜色值中的G分量—黑色
    * 第①行的k l m n o值决定新的颜色值中的B分量—大青
    * 第⑥行的p q r s t值决定新的颜色值中的A分量—光滑度
    * 矩阵A中的第伍列—e j o t值分别控制每种分量中的offset,即偏移量

想要对原图片举办颜色的调整,就要求安装好用于调整颜色的矩阵A

图片 4

原始矩阵

熟视无睹有两种情势:
一 、改变偏移量
将矩阵A的第四列的值举行修改,即改变颜色的偏移量,其他值保持开端矩阵的值

图片 5

变更颜色偏移量

  原图片各样像素点的矩阵孔雀蓝和中湖蓝的颜色分量都增多了100,红绿混合为冰雪蓝,最后会使得整张图片偏黄。
二 、改变颜色周密
修改颜色分量中的有些周到值,其余值依旧维持初阶矩阵的值

图片 6

转移颜色周全

  矩阵运算后,原图片每个像素点的矩阵樱草黄的颜色分量会化为原来的两倍,最后使得原图片的颜色偏绿。

摄像与图像OdysseyGB/YUV格式详解(转)
处理器彩色显示屏展现色彩的法则与多电视视一样,都以使用CR-V(Red)G(格林)B(Blue)相加混色的规律:通过发出出两种差别强度的电子束,使荧屏内侧覆盖的红天蓝磷光质地发光而发杰出彩那种色彩的代表方法称为ENCOREGB色彩空间表示(它也是多媒体电脑技术中用得最多的一种色彩空间表示方法)
依照三本色原理,任意一种色光F都能够用不一致分量的PAJEROGB三色相加混合而成
F = r [ R ]   g [ G ]   b [ B ]
中间,rgb分别为三本色到场混合的全面当三本色分量都为0(最弱)时混合为黄铜色光;而当三本色分量都为k(最强)时混合为蓝紫光调整rgb多个全面的值,能够勾兑出介于卡其灰光和铁黑光之间的各个三种的色光
那么YUV又从何而来呢?在现世彩色TV系统中,平常使用三管彩色录制机或彩色CCD录像机实行拍片,然后把摄得的彩色图像信号经分色分别放少校正后获得PAJEROGB,再通过矩阵变换电路获得亮度信号Y和三个色差信号LX570-Y(即U)B-Y(即V),最终发送端将亮度和色差多少个信号分别开始展览编码,用同一信道发送出去那种色彩的表示方法便是所谓的YUV色彩空间表示
运用YUV色彩空间的最首倘使它的亮度信号Y和色度信号UV是分开的比方唯有Y信号分量而尚未UV分量,那么那样表示的图像正是黑豆灰度图像彩色电视选拔YUV空间就是为了用亮度信号Y化解彩色TV与黑白电视机的包容难题,使黑白电视机也能收到彩色电视信号
YUV与帕杰罗GB互相转换的公式如下(福睿斯GB取值范围均为0-255):
Y = 0.299R   0.587G   0.114B
U = -0.147R - 0.289G   0.436B
V = 0.615R - 0.515G - 0.100B
R = Y   1.14V
G = Y - 0.39U - 0.58V
B = Y   2.03U
在DirectShow中,常见的SportageGB格式有奇骏GB1索罗德GB4福睿斯GB8LANDGB565凯雷德GB555宝马X3GB24汉兰达GB32A奥迪Q3GB32等;常见的YUV格式有YUY2YUYVYVYUUYVYAYUVY41PY411Y211IF09IYUVYV12YVU9YUV411YUV420等作为录像媒体类型的扶助表明项目(Subtype),它们对应的GUID见表2.3
表2.3 常见的RGB和YUV格式
GUID 格式描述
MEDIASUBTYPE_奥迪Q5GB1 2色,各种像素用一个人表示,须求调色板
MEDIASUBTYPE_科雷傲GB4 16色,每一种像素用三位代表,必要调色板
MEDIASUBTYPE_奇骏GB8 256色,种种像素用六人代表,须要调色板
MEDIASUBTYPE_LANDGB565 每种像素用15人表示,奥迪Q7GB分量分别选拔8个人5位8人
MEDIASUBTYPE_PAJEROGB555 每一个像素用拾陆个人表示,PRADOGB分量都施用五个人(剩下的一位不用)
MEDIASUBTYPE_福睿斯GB24 每一个像素用2肆人代表,LX570GB分量各使用5人
MEDIASUBTYPE_途锐GB32 每一个像素用叁十三位表示,卡宴GB分量各使用7位(剩下的伍位不要)
MEDIASUBTYPE_A奥迪Q5GB32 每一种像素用三12人表示,LacrosseGB分量各使用六个人(剩下的陆位用于表示Alpha通道值)
MEDIASUBTYPE_YUY2 YUY2格式,以4:2:2格局包裹
MEDIASUBTYPE_YUYV YUYV格式(实际格式与YUY2相同)
MEDIASUBTYPE_YVYU YVYU格式,以4:2:2格局卷入
MEDIASUBTYPE_UYVY UYVY格式,以4:2:2格局包裹
MEDIASUBTYPE_AYUV 带Alpha通道的4:4:4 YUV格式
MEDIASUBTYPE_Y41P Y41P格式,以4:1:1格局打包
MEDIASUBTYPE_Y411 Y411格式(实际格式与Y41P一致)
MEDIASUBTYPE_Y211 Y211格式
MEDIASUBTYPE_IF09 IF09格式
MEDIASUBTYPE_IYUV IYUV格式
MEDIASUBTYPE_YV12 YV12格式
MEDIASUBTYPE_YVU9 YVU9格式
上边分别介绍各个瑞虎GB格式
¨ 奥迪Q5GB1酷威GB4汉兰达GB8都以调色板类型的福睿斯GB格式,在描述那几个媒体类型的格式细节时,常常会在BITMAPINFOHEADEHaval数据结构后边随着一个调色板(定义一多级颜色)它们的图像数据并不是真的的水彩值,而是当前像素颜色值在调色板中的索引以HavalGB1(2色位图)为例,比如它的调色板中定义的三种颜色值依次为0x000000(天灰)和0xFFFFFF(钴蓝),那么图像数据001101010111(每个像素用1人表示)表示对应各像素的颜料为:黑黑白白黑白黑白黑白白白
¨ 中华VGB565使用1四个人表示一个像素,那15个人中的四人用于GL450,伍位用于G,五个人用于B程序中一般使用2个字(WOOdysseyD,贰个字相当多少个字节)来操作1个像素当读出二个像素后,这一个字的顺序位意义如下:
高字节 低字节
R R R R R G G G G G G B B B B B
可以组合使用屏蔽字和移动操作来获取哈弗GB各分量的值:
#define RGB565_MASK_RED 0xF800
#define RGB565_MASK_GREEN 0x07E0
#define RGB565_MASK_BLUE 0x001F
R = (wPixel & RGB565_MASK_RED) >> 11; // 取值范围0-31
G = (wPixel & RGB565_MASK_GREEN) >> 5; // 取值范围0-63
B = wPixel & RGB565_MASK_BLUE; // 取值范围0-31
¨ 奇骏GB555是另一种拾肆个人的昂科威GB格式,CRUISERGB分量都用七位代表(剩下的一人不用)使用3个字读出3个像素后,这一个字的相继位意义如下:
高字节 低字节
X 奥迪Q5 奥迪Q5 ENCORE 奥迪Q5 G G G G G B B B B B (X表示不用,能够忽略)
能够结合使用屏蔽字和活动操作来赢得卡宴GB各分量的值:
#define RGB555_MASK_RED 0x7C00
#define RGB555_MASK_GREEN 0x03E0
#define RGB555_MASK_BLUE 0x001F
R = (wPixel & RGB555_MASK_RED) >> 10; // 取值范围0-31
G = (wPixel & RGB555_MASK_GREEN) >> 5; // 取值范围0-31
B = wPixel & RGB555_MASK_BLUE; // 取值范围0-31
¨ 奇骏GB24使用2三人来代表3个像素,卡宴GB分量都用8位代表,取值范围为0-255留意在内部存款和储蓄器中奥迪Q7GB各分量的排列顺序为:BGXC90 BG卡宴 BG昂科雷平日能够选用PAJEROGBT陆风X8IPLE数据结构来操作2个像素,它的定义为:
typedef struct tagRGBTRIPLE {
BYTE rgbtBlue; // 本白分量
BYTE rgbt格林; // 浅蓝分量
BYTE rgbtRed; // 藤黄分量
} RGBTRIPLE;
¨ SportageGB32使用叁十一人来表示2个像素,奥迪Q7GB分量各用去七人,剩下的七个人用作Alpha通道可能不用(A哈弗GB32正是带Alpha通道的索罗德GB32)注目的在于内部存款和储蓄器中路虎极光GB各分量的排列顺序为:BGRA BGRA BGRA平日能够动用QashqaiGBQUAD数据结构来操作3个像素,它的定义为:
typedef struct tagRGBQUAD {
BYTE rgbBlue; // 红色分量
BYTE rgb格林; // 品红分量
BYTE rgbRed; // 天灰分量
BYTE rgbReserved; // 保留字节(用作Alpha通道或不经意)
} RGBQUAD;
上边介绍各个YUV格式YUV格式经常有两大类:打包(packed)格式和平面(planar)格式前者将YUV分量存放在同1个数组中,日常是多少个相邻的像素组成贰个宏像素(macro-pixel);而后者使用多少个数组分开存放YUV多个轻重,就如贰个三维平面一样表2.3中的YUY2到Y211都以打包格式,而IF09到YVU9都以平面格式(注意:在介绍各类具体格式时,YUV各分量都会包涵下标,如Y0U0V0代表第③个像素的YUV分量,Y1U1V1意味着第二个像素的YUV分量,以此类推)
¨ YUY2(和YUYV)格式为各个像素保留Y分量,而UV分量在档次方向上每三个像素采集样品三次1个宏像素为四个字节,实际表示叁个像素(4:2:2的情致为3个宏像素中有多少个Y分量二个U分量和二个V分量)图像数据中YUV分量排列顺序如下:
Y0 U0 Y1 V0 Y2 U2 Y3 V2
¨ YVYU格式跟YUY2类似,只是图像数据中YUV分量的排列顺序有所分化:
Y0 V0 Y1 U0 Y2 V2 Y3 U2
¨ UYVY格式跟YUY2类似,只是图像数据中YUV分量的排列顺序有所分歧:
U0 Y0 V0 Y1 U2 Y2 V2 Y3
¨ AYUV格式带有1个Alpha通道,并且为各类像素都提取YUV分量,图像数据格式如下:
A0 Y0 U0 V0 A1 Y1 U1 V1
¨ Y41P(和Y411)格式为每种像素保留Y分量,而UV分量在档次方向上每陆个像素采集样品叁遍三个宏像素为十一个字节,实际表示九个像素图像数据中YUV分量排列顺序如下:
U0 Y0 V0 Y1 U4 Y2 V4 Y3 Y4 Y5 Y6 Y8
¨ Y211格式在档次方向上Y分量每一个像素采集样品3次,而UV分量每多少个像素采样二遍三个宏像素为几个字节,实际表示伍个像素图像数据中YUV分量排列顺序如下:
Y0 U0 Y2 V0 Y4 U4 Y6 V4
¨ YVU9格式为各种像素都提取Y分量,而在UV分量的提取时,首先将图像分成若干个4 x 4的宏块,然后各类宏块提取三个U分量和1个V分量图像数据存款和储蓄时,首先是整幅图像的Y分量数组,然后就跟着U分量数组,以及V分量数组IF09格式与YVU9近似
¨ IYUV格式为各类像素都提取Y分量,而在UV分量的提取时,首先将图像分成若干个2 x 2的宏块,然后每一种宏块提取一个U分量和3个V分量YV12格式与IYUV类似
¨ YUV411YUV420格式多见于DV数据中,前者用于NTSC制,后者用于PAL制YUV411为种种像素都提取Y分量,而UV分量在档次方向上每陆个像素采集样品3遍YUV420并非V分量采集样品为0,而是跟YUV411对照,在档次方向上加强一倍色差采集样品频率,在笔直方向上以U/V间隔的格局减弱八分之四色差采集样品,如下图所示

5. Control

Control 要处理的业务相比多,如下:

  • 绑定 Model & View
  • 转变通过海关分值
  • 看清通过海关条件
  • 对外交事务件
  • 用户交互

初阶化时,Control 把 Model 的砖头单向绑定到 View 的砖块了。如下:

Object.defineProperties(model.tile, { originIndex: { get() {...}, set(){ ... view.update({originIndex}) } }, index: { get() {...}, set() { ... view.update({index}) } }, clr: { get() {...}, set() { ... view.update({clr}) } }, removed: { get() {...}, set() { ... view.update({removed}) } }, score: { get() {...}, set() { ... view.update({score}) } } })

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Object.defineProperties(model.tile, {
    originIndex: {
        get() {...},
        set(){
            ...
            view.update({originIndex})
        }
    },  
    index: {
        get() {...},
        set() {
            ...
            view.update({index})
        }
    },
    clr: {
        get() {...},
        set() {
            ...
            view.update({clr})
        }
    },
    removed: {
        get() {...},
        set() {
            ...
            view.update({removed})
        }
    },  
    score: {
        get() {...},
        set() {
            ...
            view.update({score})
        }
    }
})
 

「通过海关分值」与「判断通过海关条件」那对逻辑在本文的「游戏规则」中有有关介绍,那里不再赘言。

对外交事务件规划如下:

name detail
pass 通关
pause 暂停
resume 恢复
gameover 游戏结束

用户交互 APIs 规划如下:

name type deltail
init method 初始化游戏
next method 进入下一关
enter method 进入指定关卡
pause method 暂停
resume method 恢复
destroy method 销毁游戏

① 、画灰度图直方图

绘制都能够调用matplotlib.pyplot库来拓展,在那之中的hist函数能够一向绘制直方图。

调用方式:
n, bins, patches = plt.hist(arr, bins=50, normed=1, facecolor='green', alpha=0.75)
hist的参数非常多,但常用的就这五个,只有第一个是必须的,后面四个可选

arr: 需要计算直方图的一维数组

bins: 直方图的柱数,可选项,默认为10

normed: 是否将得到的直方图向量归一化。默认为0

facecolor: 直方图颜色

alpha: 透明度

返回值 :

n: 直方图向量,是否归一化由参数设定

bins: 返回各个bin的区间范围

patches: 返回每个bin里面包含的数据,是一个list

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
img=np.array(Image.open('len.jpg').convert('L'))

plt.figure("lena")
arr=img.flatten()
n, bins, patches = plt.hist(arr, bins=256, normed=1, facecolor='green', alpha=0.75)
print(n)
print(bins)
print(patches)
plt.show()

赢得如下图所示:图片 7

像素块分析

和图像的情调解和处理理有二种方式相同,图像的变形处理也有使用矩阵和像素块分析二种方法,drawBitmapMesh()与操纵像素点来改变色彩的规律类似,是把图像分成了2个个的小块,然后经过转移每多少个图像块来修改总体图像。

public void drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight,float[] verts, int vertOffset,  int[] colors, int colorOffset, Paint paint);

图片 8

开头图像

图片 9

反过来图像

要使用drawBitmapMesh()方法就需先将图纸分割为多少个图像块。在图像上横纵各画N条线,而那横纵各N条线就交织成了NxN个点,而种种点的坐标则以x1,y1,x2,y2,...,xn,yn的花样保留在verts数组中,也正是说verts数组的每两位用来保存一个交织点,第一个是横坐标,第二个是纵坐标。而整个drawBitmapMesh()方法改变图像的点子,便是靠那个坐标值的改观来又一次定义每2个图像块,从而完毕图像效果处理的功能。使用那么些方法能够实现无数图像特效如旗帜飘扬、水波纹等效果。

7. 结语

下边是本文介绍的「消灭星星」的线上 DEMO 的二维码:

图片 10

游戏的源码托管在:

感谢耐心阅读完本小说的读者。本文仅表示笔者的个人观点,如有不妥之处请不吝赐教。
万一对「H5游戏开发」感兴趣,欢迎关心大家的专栏。

图像打开与体现

from PIL import Image
import numpy as np
import scipy
import matplotlib.pyplot as plt
lena = Image.open('lena.jpg')           //打开图像  
print(lena.mode)                       //打印图像类型
print(lena.getpixel((0,0)))           //打印图像(0,0)处像素值
lena.show()                            //图像显示
变动色光属性

系统封装了贰个类—ColorMatrix,通过那个类,能够很方便地通过转移矩阵值来处理颜色效果(色调、饱和度、亮度)。本质上是二个一维数组[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t]。

图片 11

ColorMatrix

调节色调(色彩的转动运算):
  ColorMatrix类提供了setRotate(int axis, float degrees)来调节颜色的颜色。第伍个参数,使用0、一 、2来代表Red、Green、Blue三种颜色的拍卖,第②个参数,正是亟需处理的值。

    /**
     * Set the rotation on a color axis by the specified values.
     * <p>
     * <code>axis=0</code> correspond to a rotation around the RED color
     * <code>axis=1</code> correspond to a rotation around the GREEN color
     * <code>axis=2</code> correspond to a rotation around the BLUE color
     * </p>
     */
    public void setRotate(int axis, float degrees) {
        reset();
        double radians = degrees * Math.PI / 180d;
        float cosine = (float) Math.cos(radians);
        float sine = (float) Math.sin(radians);
        switch (axis) {
        // Rotation around the red color
        case 0:
            mArray[6] = mArray[12] = cosine;
            mArray[7] = sine;
            mArray[11] = -sine;
            break;
        // Rotation around the green color
        case 1:
            mArray[0] = mArray[12] = cosine;
            mArray[2] = -sine;
            mArray[10] = sine;
            break;
        // Rotation around the blue color
        case 2:
            mArray[0] = mArray[6] = cosine;
            mArray[1] = sine;
            mArray[5] = -sine;
            break;
        default:
            throw new RuntimeException();
        }
    }

调节饱和度
  通过色彩的移位运算单独增强Tucson,G,B的饱和度,ColorMatrix类提供了setSaturation(float sat)方法来完全调节图像的饱和度,参数代表设置颜色饱和度的值,当饱和度为0时,图像成为灰度图像,数值越大图像越饱和。

    /**
     * Set the matrix to affect the saturation of colors.
     *
     * @param sat A value of 0 maps the color to gray-scale. 1 is identity.
     */
    public void setSaturation(float sat) {
        reset();
        float[] m = mArray;

        final float invSat = 1 - sat;
        final float R = 0.213f * invSat;
        final float G = 0.715f * invSat;
        final float B = 0.072f * invSat;

        m[0] = R   sat; m[1] = G;       m[2] = B;
        m[5] = R;       m[6] = G   sat; m[7] = B;
        m[10] = R;      m[11] = G;      m[12] = B   sat;
    }

调节亮度(色彩的缩放运算)
  当三原色以平等的百分比实行混合的时候,就会彰显出乳白,使用这些原理来改变二个图像的亮度,亮度为0时,图像成为全黑。ColorMatrix类提供setScale(float rScale, float gScale, float bScale, float aScale)方法来调节颜色的亮度值。

    /**
     * Set this colormatrix to scale by the specified values.
     */
    public void setScale(float rScale, float gScale, float bScale,
                         float aScale) {
        final float[] a = mArray;

        for (int i = 19; i > 0; --i) {
            a[i] = 0;
        }
        a[0] = rScale;
        a[6] = gScale;
        a[12] = bScale;
        a[18] = aScale;
    }

3.3 加强砖墙

砖墙在解除了一部分砖石后,会现出空洞,此时内需对墙体实行狠抓:

向下夯实 向左夯实 向左下夯实(先下后左)

一种高效的兑现方案是,每一趟「消除砖块」后直接遍历砖墙数组(10×10数组)再把空洞抓好,伪代码表示如下:

JavaScript

for(let row = 0; row < 10; row) { for(let col = 0; col < 10; col) { if(isEmpty(row, col)) { // 水平方向(向左)抓牢if(isEmptyCol(col)) { tampRow(col); } // 垂直方向(向下)加强 else { tampCol(col); } break; } } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
for(let row = 0; row < 10; row) {
for(let col = 0; col < 10; col) {
if(isEmpty(row, col)) {
// 水平方向(向左)夯实
if(isEmptyCol(col)) {
tampRow(col);
}
// 垂直方向(向下)夯实
else {
tampCol(col);
}
break;
}
}
}

But… 为了狠抓二个空洞对一张大数组举行全量遍历并不是一种高效的算法。以作者之见影响「墙体抓实」成效的要素有:

  1. 稳定空洞
  2. 砖块移动(做实)

扫描墙体数组的显要指标是「定位空洞」,可是还是不是不扫描墙体数组直接「定位空洞」?

墙体的「空洞」是出于「化解砖块」造成的,换种说法 —— 被清除的砖块留下来的坑位正是墙体的肤浅。在「消除砖块」的还要标记空洞的地方,那样就不用全量扫描墙体数组,伪代码如下:

JavaScript

function deleteTile(tile) { // 标记空洞 markHollow(tile.index); // 删除砖块逻辑 ... }

1
2
3
4
5
6
function deleteTile(tile) {
// 标记空洞
markHollow(tile.index);
// 删除砖块逻辑
...
}

在上头的狠抓动图,其实能够见见它的坚实进度如下:

  1. 空洞上方的砖块向下活动
  2. 空驶列车右边的砖块向左移动

墙体在「加强」进度中,它的界线是实时在转变,借使「坚实」不按实际边界进行围观,会产生多余的空域扫描:

图片 12

怎么记录墙体的边界?
把墙体拆分成二个个独立的列,那么列最顶部的空白格片段正是墙体的「空白」,而另外非顶部的空白格片段即墙体的「空洞」。

图片 13

小编利用一组「列集合」来描述墙体的界线并记下墙体的悬空,它的模子如下:

JavaScript

/* @ count - 列砖块数 @ start - 顶部行索引 @ end - 尾部行索引 @ pitCount - 坑数 @ topPit - 最顶部的坑 @ bottomPit - 最底部的坑 */ let wall = [ {count, start, end, pitCount, topPit, bottomPit}, {count, start, end, pitCount, topPit, bottomPit}, ... ];

1
2
3
4
5
6
7
8
9
10
11
12
13
/*
@ count - 列砖块数
@ start - 顶部行索引
@ end - 底部行索引
@ pitCount - 坑数
@ topPit - 最顶部的坑
@ bottomPit - 最底部的坑
*/
let wall = [
{count, start, end, pitCount, topPit, bottomPit},
{count, start, end, pitCount, topPit, bottomPit},
...
];

以此模型能够描述墙体的三个细节:

  • 空列
  • 列的连日空洞
  • 列的非接二连三空洞
JavaScript

// 空列 if(count === 0) { ... } // 连续空洞 else if(bottomPit -
topPit   1 === pitCount) { ... } // 非连续空洞 else { ... }

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f3d2c2df29914802382-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f3d2c2df29914802382-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f3d2c2df29914802382-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f3d2c2df29914802382-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f3d2c2df29914802382-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f3d2c2df29914802382-6">
6
</div>
<div class="crayon-num" data-line="crayon-5b8f3d2c2df29914802382-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f3d2c2df29914802382-8">
8
</div>
<div class="crayon-num" data-line="crayon-5b8f3d2c2df29914802382-9">
9
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f3d2c2df29914802382-10">
10
</div>
<div class="crayon-num" data-line="crayon-5b8f3d2c2df29914802382-11">
11
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f3d2c2df29914802382-12">
12
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f3d2c2df29914802382-1" class="crayon-line">
// 空列
</div>
<div id="crayon-5b8f3d2c2df29914802382-2" class="crayon-line crayon-striped-line">
if(count === 0) { 
</div>
<div id="crayon-5b8f3d2c2df29914802382-3" class="crayon-line">
 ...
</div>
<div id="crayon-5b8f3d2c2df29914802382-4" class="crayon-line crayon-striped-line">
}
</div>
<div id="crayon-5b8f3d2c2df29914802382-5" class="crayon-line">
// 连续空洞
</div>
<div id="crayon-5b8f3d2c2df29914802382-6" class="crayon-line crayon-striped-line">
else if(bottomPit - topPit   1 === pitCount) { 
</div>
<div id="crayon-5b8f3d2c2df29914802382-7" class="crayon-line">
 ...
</div>
<div id="crayon-5b8f3d2c2df29914802382-8" class="crayon-line crayon-striped-line">
}
</div>
<div id="crayon-5b8f3d2c2df29914802382-9" class="crayon-line">
// 非连续空洞
</div>
<div id="crayon-5b8f3d2c2df29914802382-10" class="crayon-line crayon-striped-line">
else {
</div>
<div id="crayon-5b8f3d2c2df29914802382-11" class="crayon-line">
 ...
</div>
<div id="crayon-5b8f3d2c2df29914802382-12" class="crayon-line crayon-striped-line">
}
</div>
</div></td>
</tr>
</tbody>
</table>

砖块在去掉后,映射到单个列上的空洞会有三种分布形态 —— 一而再与非接二连三。

图片 14

「三番五次空洞」与「非延续空洞」的加强过程如下:

图片 15

事实上「空列」放大于墙体上,也会有「空洞」类似的遍布形态 —— 一而再与非一连。
图片 16

它的压实进度与虚空类似,那里就不赘述了。

图像通道分别与统一

恐怕以lena.jpg图像为例,达成图像通道分别合并的操作

from PIL import Image
import numpy as np
import scipy
import matplotlib.pyplot as plt

img = Image.open('len.jpg')
print(img.mode)
print(img.getpixel((0, 0)))
gray = img.convert("L")
r, g, b = img.split()  # 分离三通道
pic = Image.merge('RGB', (r, g, b))  # 合并三通道
plt.figure("beauty")
plt.subplot(2, 3, 1), plt.title('origin')
plt.imshow(img), plt.axis('off')
plt.subplot(2, 3, 2), plt.title('gray')
plt.imshow(gray, cmap='gray'), plt.axis('off')
plt.subplot(2, 3, 3), plt.title('merge')
plt.imshow(pic), plt.axis('off')
plt.subplot(2, 3, 4), plt.title('r')
plt.imshow(r, cmap='gray'), plt.axis('off')
plt.subplot(2, 3, 5), plt.title('g')
plt.imshow(g, cmap='gray'), plt.axis('off')
plt.subplot(2, 3, 6), plt.title('b')
plt.imshow(b, cmap='gray'), plt.axis('off')
plt.show()

结果如图所示 ![图片 17]

一些开源图像处理库


  • ###### GPUImage for Android

GPUImage 是iOS下2个开源的依照GPU的图像处理库,提供各个各类的图像处理滤镜,并且扶助照相机和录制机的实时滤镜。GPUImage for Android是它在Android下的实现,同样也是开源的。个中提供了几十七种普遍的图片滤镜API,且其编写制定是依据GPU渲染,处理速度相应也正如快,是1个不利的图形实时处理框架。
GitHub地址:https://github.com/CyberAgent/android-gpuimage

  • ###### ImageFilterForAndroid

支撑一百多种图片处理效果

  • ###### OpenCV

OpenCV是贰个依照BSD许可(开源)发行的跨平台总结机视觉库,能够运作在Linux、Windows、Android和Mac OS操作系统上。

参考资料:《Android群英传》

版权声明:本文由ca888发布于ca888圈内,转载请注明出处:Python 图像处理(一)PIL