Python图像处理丨带你认识图像量化处理及局部马赛克特效

摘要:本文主要讲述如何进行图像量化处理和采样处理及局部马赛克特效。

本文分享自华为云社区《[Python图像处理] 二十.图像量化处理和采样处理及局部马赛克特效》,作者: eastmount。

本文主要讲述如何进行图像量化处理和采样处理及局部马赛克特效。

一.图像量化处理

图像通常是自然界景物的客观反映,并以照片形式或视频记录的介质连续保存,获取图像的目标是从感知的数据中产生数字图像,因此需要把连续的图像数据离散化,转换为数字化图像,其工作主要包括两方面——量化和采样。数字化幅度值称为量化,数字化坐标值称为采样。本章主要讲解图像量化和采样处理的概念,并通过Python和OpenCV实现这些功能。

1.1 概述

所谓量化(Quantization),就是将图像像素点对应亮度的连续变化区间转换为单个特定值的过程,即将原始灰度图像的空间坐标幅度值离散化。量化等级越多,图像层次越丰富,灰度分辨率越高,图像的质量也越好;量化等级越少,图像层次欠丰富,灰度分辨率越低,会出现图像轮廓分层的现象,降低了图像的质量。图6-1是将图像的连续灰度值转换为0至255的灰度级的过程。

Python图像处理丨带你认识图像量化处理及局部马赛克特效

如果量化等级为2,则将使用两种灰度级表示原始图片的像素(0-255),灰度值小于128的取0,大于等于128的取128;如果量化等级为4,则将使用四种灰度级表示原始图片的像素,新图像将分层为四种颜色,0-64区间取0,64-128区间取64,128-192区间取128,192-255区间取192;依次类推。

图6-2是对比不同量化等级的“Lena”图。其中(a)的量化等级为256,(b)的量化等级为64,(c)的量化等级为16,(d)的量化等级为8,(e)的量化等级为4,(f)的量化等级为2。

Python图像处理丨带你认识图像量化处理及局部马赛克特效

1.2 操作

下面讲述Python图像量化处理相关代码操作。其核心流程是建立一张临时图片,接着循环遍历原始图像中所有像素点,判断每个像素点应该属于的量化等级,最后将临时图像显示。下述代码将灰度图像转换为两种量化等级。

# -*- coding: utf-8 -*-
import cv2  
import numpy as np  
import matplotlib.pyplot as plt
#读取原始图像
img = cv2.imread('lena.png')
#获取图像高度和宽度
height = img.shape[0]
width = img.shape[1]
#创建一幅图像
new_img = np.zeros((height, width, 3), np.uint8)
#图像量化操作 量化等级为2
for i in range(height):
 for j in range(width):
 for k in range(3): #对应BGR三分量
 if img[i, j][k] < 128:
                gray = 0
 else:
                gray = 128
 new_img[i, j][k] = np.uint8(gray)
#显示图像
cv2.imshow("src", img)
cv2.imshow("", new_img)
#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

其输出结果如图6-3所示,它将灰度图像划分为两种量化等级。

Python图像处理丨带你认识图像量化处理及局部马赛克特效

下面的代码分别比较了量化等级为2、4、8的量化处理效果。

# -*- coding: utf-8 -*-
import cv2  
import numpy as np  
import matplotlib.pyplot as plt
#读取原始图像
img = cv2.imread('lena.png')
#获取图像高度和宽度
height = img.shape[0]
width = img.shape[1]
#创建一幅图像
new_img1 = np.zeros((height, width, 3), np.uint8)
new_img2 = np.zeros((height, width, 3), np.uint8)
new_img3 = np.zeros((height, width, 3), np.uint8)
#图像量化等级为2的量化处理
for i in range(height):
 for j in range(width):
 for k in range(3): #对应BGR三分量
 if img[i, j][k] < 128:
                gray = 0
 else:
                gray = 128
            new_img1[i, j][k] = np.uint8(gray)
#图像量化等级为4的量化处理
for i in range(height):
 for j in range(width):
 for k in range(3): #对应BGR三分量
 if img[i, j][k] < 64:
                gray = 0
 elif img[i, j][k] < 128:
                gray = 64
 elif img[i, j][k] < 192:
                gray = 128
 else:
                gray = 192
            new_img2[i, j][k] = np.uint8(gray)
#图像量化等级为8的量化处理
for i in range(height):
 for j in range(width):
 for k in range(3): #对应BGR三分量
 if img[i, j][k] < 32:
                gray = 0
 elif img[i, j][k] < 64:
                gray = 32
 elif img[i, j][k] < 96:
                gray = 64
 elif img[i, j][k] < 128:
                gray = 96
 elif img[i, j][k] < 160:
                gray = 128
 elif img[i, j][k] < 192:
                gray = 160
 elif img[i, j][k] < 224:
                gray = 192
 else:
                gray = 224
            new_img3[i, j][k] = np.uint8(gray)
#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']
#显示图像
titles = [u'(a) 原始图像', u'(b) 量化-L2', u'(c) 量化-L4', u'(d) 量化-L8'] 
images = [img, new_img1, new_img2, new_img3] 
for i in xrange(4): 
 plt.subplot(2,2,i+1), plt.imshow(images[i], 'gray'), 
 plt.title(titles[i]) 
 plt.xticks([]),plt.yticks([]) 
plt.show()

输出结果如图6-4所示,该代码调用matplotlib.pyplot库绘制了四幅图像,其中(a)表示原始图像,(b)表示等级为2的量化处理,(c)表示等级为4的量化处理,(d)表示等级为8的量化处理。

Python图像处理丨带你认识图像量化处理及局部马赛克特效

1.3 K-Means聚类量化处理

上一小节的量化处理是通过遍历图像中的所有像素点,进行灰度图像的幅度值离散化处理。本小节补充一个基于K-Means聚类算法的量化处理过程,它能够将彩色图像RGB像素点进行颜色分割和颜色量化。更多知识推荐大家学习前一篇文章。

# coding: utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt
#读取原始图像
img = cv2.imread('people.png') 
#图像二维像素转换为一维
data = img.reshape((-1,3))
data = np.float32(data)
#定义中心 (type,max_iter,epsilon)
criteria = (cv2.TERM_CRITERIA_EPS +
            cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
#设置标签
flags = cv2.KMEANS_RANDOM_CENTERS
#K-Means聚类 聚集成4类
compactness, labels, centers = cv2.kmeans(data, 4, None, criteria, 10, flags)
#图像转换回uint8二维类型
centers = np.uint8(centers)
res = centers[labels.flatten()]
dst = res.reshape((img.shape))
#图像转换为RGB显示
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
dst = cv2.cvtColor(dst, cv2.COLOR_BGR2RGB)
#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']
#显示图像
titles = [u'原始图像', u'聚类量化 K=4'] 
images = [img, dst] 
for i in xrange(2): 
 plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray'), 
 plt.title(titles[i]) 
 plt.xticks([]),plt.yticks([]) 
plt.show()

输出结果如图6-4所示,它通过K-Means聚类算法将彩色人物图像的灰度聚集成四种颜色。

Python图像处理丨带你认识图像量化处理及局部马赛克特效

二.图像采样处理

2.1 概述

图像采样(Image Sampling)处理是将一幅连续图像在空间上分割成M×N个网格,每个网格用一个亮度值或灰度值来表示,其示意图如图6-5所示。

Python图像处理丨带你认识图像量化处理及局部马赛克特效

图像采样的间隔越大,所得图像像素数越少,空间分辨率越低,图像质量越差,甚至出现马赛克效应;相反,图像采样的间隔越小,所得图像像素数越多,空间分辨率越高,图像质量越好,但数据量会相应的增大。图6-6展示了不同采样间隔的“Lena”图。

Python图像处理丨带你认识图像量化处理及局部马赛克特效

2.2 操作

下面讲述Python图像采样处理相关代码操作。其核心流程是建立一张临时图片,设置需要采样的区域大小(如16×16),接着循环遍历原始图像中所有像素点,采样区域内的像素点赋值相同(如左上角像素点的灰度值),最终实现图像采样处理。代码是进行16×16采样的过程。

# -*- coding: utf-8 -*-
import cv2  
import numpy as np  
import matplotlib.pyplot as plt
#读取原始图像
img = cv2.imread('scenery.png')
#获取图像高度和宽度
height = img.shape[0]
width = img.shape[1]
#采样转换成16*16区域
numHeight = height/16
numwidth = width/16
#创建一幅图像
new_img = np.zeros((height, width, 3), np.uint8)
#图像循环采样16*16区域
for i in range(16):
 #获取Y坐标
    y = i*numHeight
 for j in range(16):
 #获取X坐标
        x = j*numwidth
 #获取填充颜色 左上角像素点
        b = img[y, x][0]
        g = img[y, x][1]
        r = img[y, x][2]
 #循环设置小区域采样
 for n in range(numHeight):
 for m in range(numwidth):
 new_img[y+n, x+m][0] = np.uint8(b)
 new_img[y+n, x+m][1] = np.uint8(g)
 new_img[y+n, x+m][2] = np.uint8(r)
#显示图像
cv2.imshow("src", img)
cv2.imshow("", new_img)
#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

输出结果如下图所示:

Python图像处理丨带你认识图像量化处理及局部马赛克特效

同样,可以对彩色图像进行采样处理,下面的代码将彩色风景图像采样处理成8×8的马赛克区域。

# -*- coding: utf-8 -*-
import cv2  
import numpy as np  
import matplotlib.pyplot as plt
#读取原始图像
img = cv2.imread('scenery.png')
#获取图像高度和宽度
height = img.shape[0]
width = img.shape[1]
#采样转换成8*8区域
numHeight = height/8
numwidth = width/8
#创建一幅图像
new_img = np.zeros((height, width, 3), np.uint8)
#图像循环采样8*8区域
for i in range(8):
 #获取Y坐标
    y = i*numHeight
 for j in range(8):
 #获取X坐标
        x = j*numwidth
 #获取填充颜色 左上角像素点
        b = img[y, x][0]
        g = img[y, x][1]
        r = img[y, x][2]
 #循环设置小区域采样
 for n in range(numHeight):
 for m in range(numwidth):
 new_img[y+n, x+m][0] = np.uint8(b)
 new_img[y+n, x+m][1] = np.uint8(g)
 new_img[y+n, x+m][2] = np.uint8(r)
#显示图像
cv2.imshow("src", img)
cv2.imshow("Sampling", new_img)
#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

其输出结果如图所示,它将彩色风景图像采样成8×8的区域。

Python图像处理丨带你认识图像量化处理及局部马赛克特效

但上述代码存在一个问题,当图像的长度和宽度不能被采样区域整除时,输出图像的最右边和最下边的区域没有被采样处理。这里推荐读者做个求余运算,将不能整除部门的区域也进行采样处理。

Python图像处理丨带你认识图像量化处理及局部马赛克特效

2.3 局部马赛克处理

前面讲述的代码是对整幅图像进行采样处理,那么如何对图像的局部区域进行马赛克处理呢?下面的代码就实现了该功能。当鼠标按下时,它能够给鼠标拖动的区域打上马赛克,并按下“s”键保存图像至本地。

# -- coding:utf-8 --
import cv2  
import numpy as np  
import matplotlib.pyplot as plt
#读取原始图像
im = cv2.imread('people.png', 1)
#设置鼠标左键开启
en = False
#鼠标事件
def draw(event, x, y, flags, param):
 global en
 #鼠标左键按下开启en值
 if event==cv2.EVENT_LBUTTONDOWN:
 en = True
 #鼠标左键按下并且移动
elif event==cv2.EVENT_MOUSEMOVE and
 flags==cv2.EVENT_LBUTTONDOWN:
 #调用函数打马赛克
 if en:
 drawMask(y,x)
 #鼠标左键弹起结束操作
 elif event==cv2.EVENT_LBUTTONUP:
 en = False
#图像局部采样操作 
def drawMask(x, y, size=10):
 #size*size采样处理
    m = x / size * size  
    n = y / size * size
 print m, n
 #10*10区域设置为同一像素值
 for i in range(size):
 for j in range(size):
 im[m+i][n+j] = im[m][n]
#打开对话框
cv2.namedWindow('image')
#调用draw函数设置鼠标操作
cv2.setMouseCallback('image', draw)
#循环处理
while(1):
    cv2.imshow('image', im)
 #按ESC键退出
 if cv2.waitKey(10)&0xFF==27:
 break
 #按s键保存图片
 elif cv2.waitKey(10)&0xFF==115:
        cv2.imwrite('sava.png', im)
#退出窗口
cv2.destroyAllWindows()

其输出结果如图所示,它将人物的脸部进行马赛克处理。

Python图像处理丨带你认识图像量化处理及局部马赛克特效

 

点击关注,第一时间了解华为云新鲜技术~

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python图像处理丨带你认识图像量化处理及局部马赛克特效 - Python技术站

(0)
上一篇 2023年4月2日
下一篇 2023年4月2日

相关文章

  • Istio数据面新模式:Ambient Mesh技术解析

    摘要:Ambient Mesh以一种更符合大规模落地要求的形态出现,克服了大多数Sidecar模式的固有缺陷,让用户无需再感知网格相关组件,真正将网格下沉为基础设施。 本文分享自华为云社区《华为云云原生团队:Istio数据面新模式 Ambient Mesh技术解析》,作者: 云容器大未来。 如果说在以Kubernetes为基础构建起的云原生世界里,哪种设计模…

    云计算 2023年5月6日
    00
  • 盘点Python 中字符串的常用操作

    摘要:盘点 Python 中字符串的几个常用操作,对新手极度的友好。 本文分享自华为云社区《盘点 Python 中字符串的常用操作,对新手极度友好》,作者:TT-千叶 。 在 Python 中字符串的表达方式有四种 一对单引号一对双引号一对三个单引号一对三个双引号a = ‘abc’b= “abc”c = ‘’‘abc’’’d = “”“abc”””print…

    Python开发 2023年4月2日
    00
  • 一文读懂华为云云原生产品及开源实践

    摘要:本文主要从华为云原生产品及开源产品两个层面进行展开,详述华为云在云原生领域的最佳实践。 本文分享自华为云社区《【云驻共创】华为云云原生产品及开源实践》,作者:kaliarch。 一 云原生发展阶段和趋势 回首过去,云计算的快速发展,为众多行业的数字化转型提供了推力,也提升了企业数字化转型的技术革新,将科技创新与商业元素的不断融合,又催生出新的业务形态。…

    云计算 2023年4月17日
    00
  • Python图像处理丨认识图像锐化和边缘提取的4个算子

    摘要:图像锐化和边缘提取技术可以消除图像中的噪声,提取图像信息中用来表征图像的一些变量,为图像识别提供基础。 本文分享自华为云社区《[Python图像处理] 十七.图像锐化与边缘检测之Roberts算子、Prewitt算子、Sobel算子和Laplacian算》,作者: eastmount 。 由于收集图像数据的器件或传输数图像的通道的存在一些质量缺陷,文物…

    2023年4月2日
    00
  • 掌握动态规划,从“什么问题适合用”及“解题思路”入手

    摘要:一般是用动态规划来解决最优问题。 本文分享自华为云社区《深入浅出动态规划算法(中)》,作者:嵌入式视觉 。 一,“一个模型三个特征”理论讲解 一个模型指的是适合用动态规划算法解决的问题的模型,这个模型也被定义为“多阶段决策最优解模型”。具体解释如下: 一般是用动态规划来解决最优问题。而解决问题的过程,需要经历多个决策阶段。每个决策阶段都对应着一组状态。…

    人工智能概论 2023年4月24日
    00
  • Karmada v1.5发布:多调度组助力成本优化

    摘要:在最新发布的1.5版本中,Karmada 提供了多调度组的能力,利用该能力,用户可以实现将业务优先调度到成本更低的集群,或者在主集群故障时,优先迁移业务到指定的备份集群。 本文分享自华为云社区《Karmada v1.5发布!多调度组助力成本优化》,作者:华为云云原生团队。 Karmada 是开放的多云多集群容器编排引擎,旨在帮助用户在多云环境下部署和运…

    云计算 2023年4月19日
    00
  • 从源码角度深入解析Callable接口

    摘要:从源码角度深入解析Callable接口,希望大家踏下心来,打开你的IDE,跟着文章看源码,相信你一定收获不小。 本文分享自华为云社区《一个Callable接口能有多少知识点?》,作者: 冰 河。 并发编程一直是程序员们比较头疼的,如何编写正确的并发程序相比其他程序来说,是一件比较困难的事情,并发编程中出现的 Bug 往往也是特别诡异的。 之所以说并发编…

    Java 2023年4月18日
    00
  • 华为亮相KubeCon EU 2023 新云原生开源项目Kuasar推动“云上演进”

    摘要:协力同行、拥抱开源,解放数字生产力,为社会和行业带来更多价值。 在数字时代,如果说企业是一艘巨大的货船,那么云原生则为企业的每一个业务、每一个应用提供了标准化的集装箱,摆脱笨重的底层桎梏,打造新一代云操作系统,驾驶这轮“货船”航向数字化的未来世界。 4月18日—21日,一年一度的云原生开源领域顶级峰会KubeCon & CloudNativeC…

    云计算 2023年4月25日
    00
合作推广
合作推广
分享本页
返回顶部