## [Python图像处理] 三十.图像量化及采样处理万字详细总结（推荐）

osc_c9pkd6zt 2020-11-11 07:43:10
OpenCV

# 一.图像量化处理

## 2.操作

``````# -*- coding: utf-8 -*-
# BY:Eastmount CSDN 2020-11-10
import cv2
import numpy as np
import matplotlib.pyplot as plt

#读取原始图像

#获取图像高度和宽度
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("Quantization", new_img)

#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()
``````

``````# -*- coding: utf-8 -*-
# BY:Eastmount CSDN 2020-11-10
import cv2
import numpy as np
import matplotlib.pyplot as plt

#读取原始图像

#获取图像高度和宽度
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 = ['(a) 原始图像', '(b) 量化-L2', '(c) 量化-L4', '(d) 量化-L8']
images = [img, new_img1, new_img2, new_img3]
for i in range(4):
plt.subplot(2,2,i+1), plt.imshow(images[i], 'gray'),
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
``````

## 3.K-Means聚类量化处理

``````# coding: utf-8
# BY:Eastmount CSDN 2020-11-10
import cv2
import numpy as np
import matplotlib.pyplot as plt
#读取原始图像
#图像二维像素转换为一维
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 = ['原始图像', '聚类量化 K=4']
images = [img, dst]
for i in range(2):
plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray'),
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
``````

# 二.图像采样处理

## 2.操作

``````# -*- coding: utf-8 -*-
# BY:Eastmount CSDN 2020-11-10
import cv2
import numpy as np
import matplotlib.pyplot as plt

#读取原始图像

#获取图像高度和宽度
height = img.shape[0]
width = img.shape[1]

#采样转换成16*16区域
numHeight = int(height/16)
numWidth = int(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("Sampling", new_img)

#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()
``````

``````# -*- coding: utf-8 -*-
# BY:Eastmount CSDN 2020-11-10
import cv2
import numpy as np
import matplotlib.pyplot as plt

#读取原始图像

#获取图像高度和宽度
height = img.shape[0]
width = img.shape[1]

#采样转换成8*8区域
numHeight = int(height/8)
numwidth = int(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()
``````

## 3.局部马赛克处理

``````# -- coding:utf-8 --
# BY:Eastmount CSDN 2020-11-10
import cv2
import numpy as np
import matplotlib.pyplot as plt
#读取原始图像
#设置鼠标左键开启
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:
#鼠标左键弹起结束操作
elif event==cv2.EVENT_LBUTTONUP:
en = False
#图像局部采样操作
#size*size采样处理
m = int(x / size * size)
n = int(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()
``````

# 三.图像金字塔

## 1.图像向下取样

• dst = pyrDown(src[, dst[, dstsize[, borderType]]])
– src表示输入图像，
– dst表示输出图像，和输入图像具有一样的尺寸和类型
– dstsize表示输出图像的大小，默认值为Size()
– borderType表示像素外推方法，详见cv::bordertypes

``````# -*- coding: utf-8 -*-
# BY:Eastmount CSDN 2020-11-10
import cv2
import numpy as np
import matplotlib.pyplot as plt
#读取原始图像
#图像向下取样
r = cv2.pyrDown(img)
#显示图像
cv2.imshow('original', img)
cv2.imshow('PyrDown', r)
cv2.waitKey()
cv2.destroyAllWindows()
``````

``````# -*- coding: utf-8 -*-
# BY:Eastmount CSDN 2020-11-10
import cv2
import numpy as np
import matplotlib.pyplot as plt
#读取原始图像
#图像向下取样
r1 = cv2.pyrDown(img)
r2 = cv2.pyrDown(r1)
r3 = cv2.pyrDown(r2)
#显示图像
cv2.imshow('original', img)
cv2.imshow('PyrDown1', r1)
cv2.imshow('PyrDown2', r2)
cv2.imshow('PyrDown3', r3)
cv2.waitKey()
cv2.destroyAllWindows()
``````

## 2.图像向上取样

• dst = pyrUp(src[, dst[, dstsize[, borderType]]])
– src表示输入图像，
– dst表示输出图像，和输入图像具有一样的尺寸和类型
– dstsize表示输出图像的大小，默认值为Size()
– borderType表示像素外推方法，详见cv::bordertypes

``````# -*- coding: utf-8 -*-
# BY:Eastmount CSDN 2020-11-10
import cv2
import numpy as np
import matplotlib.pyplot as plt
#读取原始图像
#图像向上取样
r = cv2.pyrUp(img)
#显示图像
cv2.imshow('original', img)
cv2.imshow('PyrUp', r)
cv2.waitKey()
cv2.destroyAllWindows()
``````

``````# -*- coding: utf-8 -*-
import cv2
import numpy as np
import matplotlib.pyplot as plt
#读取原始图像
#图像向上取样
r1 = cv2.pyrUp(img)
r2 = cv2.pyrUp(r1)
r3 = cv2.pyrUp(r2)
#显示图像
cv2.imshow('original', img)
cv2.imshow('PyrUp1', r1)
cv2.imshow('PyrUp2', r2)
cv2.imshow('PyrUp3', r3)
cv2.waitKey()
cv2.destroyAllWindows()
``````

# 四.本章小结

2020年8月18新开的“娜璋AI安全之家”，主要围绕Python大数据分析、网络空间安全、人工智能、Web渗透及攻防技术进行讲解，同时分享CCF、SCI、南核北核论文的算法实现。娜璋之家会更加系统，并重构作者的所有文章，从零讲解Python和安全，写了近十年文章，真心想把自己所学所感所做分享出来，还请各位多多指教，真诚邀请您的关注！谢谢。

(By:Eastmount 2020-11-10 深夜10点夜于武汉 http://blog.csdn.net/eastmount/ )

[1] 冈萨雷斯著. 数字图像处理（第3版）[M]. 北京：电子工业出版社，2013.
[2] yunfung. 数字图像基础之图像取样和量化（Image Sampling and Quantization）[EB/OL]. (2017-04-23). https://www.cnblogs.com/yunfung/p/6753337.html.
[3] 阮秋琦. 数字图像处理学（第3版）[M]. 北京：电子工业出版社，2008.
[4] zqhwando. 图像处理中的采样与量化[EB/OL]. (2017-12-22). https://blog.csdn.net/zqhwando/article/details/78871140.
[5] eastmount. [数字图像处理] 三.MFC实现图像灰度、采样和量化功能详解[EB/OL]. (2015-05-28). https://blog.csdn.net/eastmount/article/details/46010637.
[6] 师寇. Python + opencv 实现图片马赛克[EB/OL]. (2017-11-08). https://blog.csdn.net/weixin_38283159/article/details/78479791.
[7] 毛星云，冷雪飞. OpenCV3编程入门[M]. 北京：电子工业出版社，2015.

https://my.oschina.net/u/4364002/blog/4711962