您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > Python

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

时间:2022-09-14 14:05:43  来源:知乎  作者:程序员之家

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

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

一.图像量化处理

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

1.1 概述

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

如果量化等级为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。

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所示,它将灰度图像划分为两种量化等级。

下面的代码分别比较了量化等级为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的量化处理。

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聚类算法将彩色人物图像的灰度聚集成四种颜色。

二.图像采样处理

2.1 概述

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

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

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()

输出结果如下图所示:

同样,可以对彩色图像进行采样处理,下面的代码将彩色风景图像采样处理成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的区域。

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

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()

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

 



Tags:Python   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
一篇文章教会你使用Python中三种简单的函数
所谓函数,就是指:把某些特定功能的代码组成为一个整体,这个整体就叫做函数。一、函数简介所谓函数,就是指:把某些特定功能的代码组成为一个整体,这个整体就叫做函数。二、函数定义...【详细内容】
2024-04-11  Search: Python  点击:(3)  评论:(0)  加入收藏
一篇文章带你了解Python的分布式进程接口
在Thread和Process中,应当优选Process,因为Process更稳定,而且,Process可以分布到多台机器上,而Thread最多只能分布到同一台机器的多个CPU上。一、前言在Thread和Process中,应当优...【详细内容】
2024-04-11  Search: Python  点击:(2)  评论:(0)  加入收藏
Python 可视化:Plotly 库使用基础
当使用 Plotly 进行数据可视化时,我们可以通过以下示例展示多种绘图方法,每个示例都会有详细的注释和说明。1.创建折线图import plotly.graph_objects as go# 示例1: 创建简单...【详细内容】
2024-04-01  Search: Python  点击:(8)  评论:(0)  加入收藏
Python 办公神器:教你使用 Python 批量制作 PPT
介绍本文将介绍如何使用openpyxl和pptx库来批量制作PPT奖状。本文假设你已经安装了python和这两个库。本文的场景是:一名基层人员,要给一次比赛活动获奖的500名选手制作奖状,并...【详细内容】
2024-03-26  Search: Python  点击:(18)  评论:(0)  加入收藏
Python实现工厂模式、抽象工厂,单例模式
工厂模式是一种常见的设计模式,它可以帮助我们创建对象的过程更加灵活和可扩展。在Python中,我们可以使用函数和类来实现工厂模式。一、Python中实现工厂模式工厂模式是一种常...【详细内容】
2024-03-07  Search: Python  点击:(34)  评论:(0)  加入收藏
不可不学的Python技巧:字典推导式使用全攻略
Python的字典推导式是一种优雅而强大的工具,用于创建字典(dict)。这种方法不仅代码更加简洁,而且执行效率高。无论你是Python新手还是有经验的开发者,掌握字典推导式都将是你技能...【详细内容】
2024-02-22  Search: Python  点击:(35)  评论:(0)  加入收藏
如何进行Python代码的代码重构和优化?
Python是一种高级编程语言,它具有简洁、易于理解和易于维护的特点。然而,代码重构和优化对于保持代码质量和性能至关重要。什么是代码重构?代码重构是指在不改变代码外部行为的...【详细内容】
2024-02-22  Search: Python  点击:(36)  评论:(0)  加入收藏
Python开发者必备的八个PyCharm插件
在编写代码的过程中,括号几乎无处不在,以至于有时我们会拼命辨别哪个闭合括号与哪个开头的括号相匹配。这款插件能帮助解决这个众所周知的问题。前言在PyCharm中浏览插件列表...【详细内容】
2024-01-26  Search: Python  点击:(89)  评论:(0)  加入收藏
Python的Graphlib库,再也不用手敲图结构了
Python中的graphlib库是一个功能强大且易于使用的工具。graphlib提供了许多功能,可以帮助您创建、操作和分析图形对象。本文将介绍graphlib库的主要用法,并提供一些示例代码和...【详细内容】
2024-01-26  Search: Python  点击:(88)  评论:(0)  加入收藏
大语言模型插件功能在携程的Python实践
作者简介成学,携程高级安全研发工程师,关注Python/Golang后端开发、大语言模型等领域。一、背景2023年初,科技圈最火爆的话题莫过于大语言模型了,它是一种全新的聊天机器人模型,...【详细内容】
2024-01-26  Search: Python  点击:(76)  评论:(0)  加入收藏
▌简易百科推荐
一篇文章教会你使用Python中三种简单的函数
所谓函数,就是指:把某些特定功能的代码组成为一个整体,这个整体就叫做函数。一、函数简介所谓函数,就是指:把某些特定功能的代码组成为一个整体,这个整体就叫做函数。二、函数定义...【详细内容】
2024-04-11  Go语言进阶学习  微信公众号  Tags:Python   点击:(3)  评论:(0)  加入收藏
一篇文章带你了解Python的分布式进程接口
在Thread和Process中,应当优选Process,因为Process更稳定,而且,Process可以分布到多台机器上,而Thread最多只能分布到同一台机器的多个CPU上。一、前言在Thread和Process中,应当优...【详细内容】
2024-04-11  Go语言进阶学习    Tags:Python   点击:(2)  评论:(0)  加入收藏
Python 可视化:Plotly 库使用基础
当使用 Plotly 进行数据可视化时,我们可以通过以下示例展示多种绘图方法,每个示例都会有详细的注释和说明。1.创建折线图import plotly.graph_objects as go# 示例1: 创建简单...【详细内容】
2024-04-01  Python技术    Tags:Python   点击:(8)  评论:(0)  加入收藏
Python 办公神器:教你使用 Python 批量制作 PPT
介绍本文将介绍如何使用openpyxl和pptx库来批量制作PPT奖状。本文假设你已经安装了python和这两个库。本文的场景是:一名基层人员,要给一次比赛活动获奖的500名选手制作奖状,并...【详细内容】
2024-03-26  Python技术  微信公众号  Tags:Python   点击:(18)  评论:(0)  加入收藏
Python实现工厂模式、抽象工厂,单例模式
工厂模式是一种常见的设计模式,它可以帮助我们创建对象的过程更加灵活和可扩展。在Python中,我们可以使用函数和类来实现工厂模式。一、Python中实现工厂模式工厂模式是一种常...【详细内容】
2024-03-07  Python都知道  微信公众号  Tags:Python   点击:(34)  评论:(0)  加入收藏
不可不学的Python技巧:字典推导式使用全攻略
Python的字典推导式是一种优雅而强大的工具,用于创建字典(dict)。这种方法不仅代码更加简洁,而且执行效率高。无论你是Python新手还是有经验的开发者,掌握字典推导式都将是你技能...【详细内容】
2024-02-22  子午Python  微信公众号  Tags:Python技巧   点击:(35)  评论:(0)  加入收藏
如何进行Python代码的代码重构和优化?
Python是一种高级编程语言,它具有简洁、易于理解和易于维护的特点。然而,代码重构和优化对于保持代码质量和性能至关重要。什么是代码重构?代码重构是指在不改变代码外部行为的...【详细内容】
2024-02-22  编程技术汇    Tags:Python代码   点击:(36)  评论:(0)  加入收藏
Python开发者必备的八个PyCharm插件
在编写代码的过程中,括号几乎无处不在,以至于有时我们会拼命辨别哪个闭合括号与哪个开头的括号相匹配。这款插件能帮助解决这个众所周知的问题。前言在PyCharm中浏览插件列表...【详细内容】
2024-01-26  Python学研大本营  微信公众号  Tags:PyCharm插件   点击:(89)  评论:(0)  加入收藏
Python的Graphlib库,再也不用手敲图结构了
Python中的graphlib库是一个功能强大且易于使用的工具。graphlib提供了许多功能,可以帮助您创建、操作和分析图形对象。本文将介绍graphlib库的主要用法,并提供一些示例代码和...【详细内容】
2024-01-26  科学随想录  微信公众号  Tags:Graphlib库   点击:(88)  评论:(0)  加入收藏
Python分布式爬虫打造搜索引擎
简单分布式爬虫结构主从模式是指由一台主机作为控制节点负责所有运行网络爬虫的主机进行管理,爬虫只需要从控制节点那里接收任务,并把新生成任务提交给控制节点就可以了,在这个...【详细内容】
2024-01-25  大雷家吃饭    Tags:Python   点击:(59)  评论:(0)  加入收藏
站内最新
站内热门
站内头条