本文系转载,原文地址:https://blog.csdn.net/wanzhen4330/article/details/84317071

目录

  • 1.读取原始图像
  • 2.网格划分,将图像划分为m*n块
    • 2.1分块后图像的存储问题
    • 2.2图像的裁剪
    • 2.3图像长宽的整除问题
      • 方法一:四舍五入法
      • 方法二:图像缩放法
  • 3.显示分块后的图像
  • 4.分块图像的还原
  • 5.参考文献

  基本思路:根据图像尺寸创建一个 ( m + 1 ) × ( n + 1 ) ( m + 1 ) × ( n + 1 ) ( m + 1 ) × ( n + 1 ) (m+1)×(n+1)(m+1)×(n+1) (m+1) \times(n+1) (m+1)×(n+1)(m+1)×(n+1)(m+1)×(n+1) (m+1)×(n+1)个均匀的网格顶点坐标,对于图像块来说每个图像块的左上角和右下角可以唯一确定一个图像块,这样就可以利用网格顶点坐标对原始图像进行裁剪。
  注意:完整的Python源程序可以在我的CSDN上下载( 点击进入下载界面),没有积分的小伙伴把下面的各个程序整理起来即可。

1.读取原始图像

import numpy as np
import matplotlib.pyplot as plt
import cv2

img = cv2.imread(‘cat.jpg’)
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)

h, w = img.shape[0], img.shape[1]
fig1 = plt.figure(‘原始图像’)
plt.imshow(img)
plt.axis(‘off’)
plt.title(‘Original image’)
print( ‘\t\t\t 原始图像形状:\n’, ‘\t\t\t’,img.shape )

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13


2.网格划分,将图像划分为m*n块

  这里有三个要点:图像的存储问题,图像的裁剪方法,长宽不能整除的问题。下面逐一介绍

2.1分块后图像的存储问题

  由于事先不知道m和n的具体值,因此也就不知道图像的分块数目具体是多少个。必须想个办法来存储这 m × n m × n m × n m×nm×n m\times n m×nm×nm×n3×1两个图像块,这会导致图像分块的不均匀,也会导致前面的五维张量不合理。一般来说,我们要分块的图像都是很大的,而划分的块数一般不会特别多,所以舍入误差带来的几个像素的差异完全可以忽略,针对这种情况,一个比较好的思路就是在五维张量的填充中只对已知位置的像素进行填充,而把其他位置的像素值仍然设置为0。
完整程序为:

def divide_method1(img,m,n):#分割成m行n列h, w = img.shape[0],img.shape[1]gx=np.round(gx).astype(np.int)gy=np.round(gy).astype(np.int)
divide_image <span class="token operator">=</span> np<span class="token punctuation">.</span>zeros<span class="token punctuation">(</span><span class="token punctuation">[</span>m<span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">,</span> n<span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token builtin">int</span><span class="token punctuation">(</span>h<span class="token operator">*</span><span class="token number">1.0</span><span class="token operator">/</span><span class="token punctuation">(</span>m<span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token number">0.5</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">int</span><span class="token punctuation">(</span>w<span class="token operator">*</span><span class="token number">1.0</span><span class="token operator">/</span><span class="token punctuation">(</span>n<span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token number">0.5</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> np<span class="token punctuation">.</span>uint8<span class="token punctuation">)</span><span class="token comment">#这是一个五维的张量,前面两维表示分块后图像的位置(第m行,第n列),后面三维表示每个分块后的图像信息</span>
<span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span>m<span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">:</span><span class="token keyword">for</span> j <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span>n<span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">:</span>      divide_image<span class="token punctuation">[</span>i<span class="token punctuation">,</span>j<span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">:</span>gy<span class="token punctuation">[</span>i<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">[</span>j<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token operator">-</span>gy<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">:</span>gx<span class="token punctuation">[</span>i<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">[</span>j<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token operator">-</span>gx<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">,</span><span class="token punctuation">:</span><span class="token punctuation">]</span><span class="token operator">=</span> img<span class="token punctuation">[</span>gy<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">:</span>gy<span class="token punctuation">[</span>i<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">[</span>j<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> gx<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">:</span>gx<span class="token punctuation">[</span>i<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">[</span>j<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span><span class="token punctuation">:</span><span class="token punctuation">]</span><span class="token comment">#这样写比a[i,j,...]=要麻烦,但是可以避免网格分块的时候,有些图像块的比其他图像块大一点或者小一点的情况引起程序出错</span>
<span class="token keyword">return</span> divide_image

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
方法二:图像缩放法

  这个方法很简单,将图像缩放一下,让其满足整除关系即可。

def divide_method2(img,m,n):#分割成m行n列h, w = img.shape[0],img.shape[1]grid_h=int(h*1.0/(m-1)+0.5)#每个网格的高grid_w=int(w*1.0/(n-1)+0.5)#每个网格的宽
<span class="token comment">#满足整除关系时的高、宽</span>
h<span class="token operator">=</span>grid_h<span class="token operator">*</span><span class="token punctuation">(</span>m<span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span>
w<span class="token operator">=</span>grid_w<span class="token operator">*</span><span class="token punctuation">(</span>n<span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token comment">#图像缩放</span>
img_re<span class="token operator">=</span>cv2<span class="token punctuation">.</span>resize<span class="token punctuation">(</span>img<span class="token punctuation">,</span><span class="token punctuation">(</span>w<span class="token punctuation">,</span>h<span class="token punctuation">)</span><span class="token punctuation">,</span>cv2<span class="token punctuation">.</span>INTER_LINEAR<span class="token punctuation">)</span><span class="token comment"># 也可以用img_re=skimage.transform.resize(img, (h,w)).astype(np.uint8)</span>
<span class="token comment">#plt.imshow(img_re)</span>
gx<span class="token punctuation">,</span> gy <span class="token operator">=</span> np<span class="token punctuation">.</span>meshgrid<span class="token punctuation">(</span>np<span class="token punctuation">.</span>linspace<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> w<span class="token punctuation">,</span> n<span class="token punctuation">)</span><span class="token punctuation">,</span>np<span class="token punctuation">.</span>linspace<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> h<span class="token punctuation">,</span> m<span class="token punctuation">)</span><span class="token punctuation">)</span>
gx<span class="token operator">=</span>gx<span class="token punctuation">.</span>astype<span class="token punctuation">(</span>np<span class="token punctuation">.</span><span class="token builtin">int</span><span class="token punctuation">)</span>
gy<span class="token operator">=</span>gy<span class="token punctuation">.</span>astype<span class="token punctuation">(</span>np<span class="token punctuation">.</span><span class="token builtin">int</span><span class="token punctuation">)</span>divide_image <span class="token operator">=</span> np<span class="token punctuation">.</span>zeros<span class="token punctuation">(</span><span class="token punctuation">[</span>m<span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">,</span> n<span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">,</span> grid_h<span class="token punctuation">,</span> grid_w<span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> np<span class="token punctuation">.</span>uint8<span class="token punctuation">)</span><span class="token comment">#这是一个五维的张量,前面两维表示分块后图像的位置(第m行,第n列),后面三维表示每个分块后的图像信息</span><span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span>m<span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">:</span><span class="token keyword">for</span> j <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span>n<span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">:</span>      divide_image<span class="token punctuation">[</span>i<span class="token punctuation">,</span>j<span class="token punctuation">,</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">]</span><span class="token operator">=</span>img_re<span class="token punctuation">[</span>gy<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">:</span>gy<span class="token punctuation">[</span>i<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">[</span>j<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> gx<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">:</span>gx<span class="token punctuation">[</span>i<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">[</span>j<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span><span class="token punctuation">:</span><span class="token punctuation">]</span>
<span class="token keyword">return</span> divide_image

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

3.显示分块后的图像

def display_blocks(divide_image):#    m,n=divide_image.shape[0],divide_image.shape[1]for i in range(m):for j in range(n):plt.subplot(m,n,i*n+j+1)plt.imshow(divide_image[i,j,:])plt.axis('off')plt.title('block:'+str(i*n+j+1))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

方法一:四舍五入法

m=3
n=4
divide_image1=divide_method1(img,m+1,n+1)#该函数中m+1和n+1表示网格点个数,m和n分别表示分块的块数
fig2 = plt.figure('分块后的子图像:四舍五入法')
display_blocks(divide_image1)
  • 1
  • 2
  • 3
  • 4
  • 5


方法二:图像缩放法

divide_image2=divide_method2(img,m+1,n+1)#该函数中m+1和n+1表示网格点个数,m和n分别表示分块的块数
fig3 = plt.figure('分块后的子图像:图像缩放法')
display_blocks(divide_image2)
  • 1
  • 2
  • 3

4.分块图像的还原

主要目的是将分块后的图像拼接起来,还原成一幅完整的大图像。有两个方法:
  1.使用opencv。其实opencv自带的有图像拼接的函数,hconcat函数:用于两个Mat矩阵或者图像的水平拼接;vconcat函数:用于两个Mat矩阵或者图像的垂直拼接。
  2.自己动手写。图像拼接是图像分块的逆过程,首先创建一个空的还原后的图像,然后将对于位置填充上对应的像素即可。
  由于事先不知道具体分成多少块,使用opencv拼接图像是很麻烦的。为了简单,我们还是选择第2种方法,自己动手丰衣足食!

def image_concat(divide_image):m,n,grid_h, grid_w=[divide_image.shape[0],divide_image.shape[1],#每行,每列的图像块数divide_image.shape[2],divide_image.shape[3]]#每个图像块的尺寸
restore_image <span class="token operator">=</span> np<span class="token punctuation">.</span>zeros<span class="token punctuation">(</span><span class="token punctuation">[</span>m<span class="token operator">*</span>grid_h<span class="token punctuation">,</span> n<span class="token operator">*</span>grid_w<span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> np<span class="token punctuation">.</span>uint8<span class="token punctuation">)</span>
restore_image<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">:</span>grid_h<span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">:</span><span class="token punctuation">]</span>
<span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span>m<span class="token punctuation">)</span><span class="token punctuation">:</span><span class="token keyword">for</span> j <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span><span class="token punctuation">:</span>restore_image<span class="token punctuation">[</span>i<span class="token operator">*</span>grid_h<span class="token punctuation">:</span><span class="token punctuation">(</span>i<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token operator">*</span>grid_h<span class="token punctuation">,</span>j<span class="token operator">*</span>grid_w<span class="token punctuation">:</span><span class="token punctuation">(</span>j<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token operator">*</span>grid_w<span class="token punctuation">]</span><span class="token operator">=</span>divide_image<span class="token punctuation">[</span>i<span class="token punctuation">,</span>j<span class="token punctuation">,</span><span class="token punctuation">:</span><span class="token punctuation">]</span>
<span class="token keyword">return</span> restore_image

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

下面分别显示‘四舍五入法’和‘图像缩放法’得到的分块图像的还原结果。

fig4 = plt.figure('分块图像的还原')
restore_image1=image_concat(divide_image1)#四舍五入法分块还原
restore_image2=image_concat(divide_image2)#图像缩放法分块还原
plt.subplot(1,2,1)
plt.imshow(restore_image1)
plt.axis('off')
plt.title('Rounding')
plt.subplot(1,2,2)
plt.imshow(restore_image2)
plt.axis('off')
plt.title('Scaling')
print('\t\t\t还原后的图像尺寸')
print('\t‘四舍五入法’:', restore_image1.shape,'\t''‘图像缩放法’:', restore_image2.shape)
plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14


5.参考文献

[1]图像的水平方向或者垂直方向拼接https://blog.csdn.net/mangobar/article/details/79656417

        </div><link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-7b4cdcb592.css" rel="stylesheet"></div>

Python对图像进行分块及复原相关推荐

  1. OpenCV自适应直方图均衡CLAHE图像和分块大小不能整除的处理

    一.引言 最近一个月来都在研究OpenCV 中CLAHE算法的一些问题,如: 图像横向和纵向分块大小与图像的宽和高不能整除怎么处理? CLIP的剪裁是怎么实施的? 解决棋盘效应的具体插值处理过程怎样? ...

  2. Python 对图像进行base64编码及解码读取为numpy、opencv、matplot需要的格式

    Python 对图像进行base64编码及解码读取为numpy.opencv.matplot需要的格式 1. 效果图 2. 源码 参考 这篇博客将介绍Python如何对图像进行base64编解码及读取 ...

  3. 使用OpenCV和Python计算图像的“彩色度”

    使用OpenCV和Python计算图像"彩色度" 1. 效果图 2. 炫彩度量方法是什么? 3. 源代码 参考 你是否尝试过计算每个图像的炫彩值,并根据炫彩值对自己的图像数据集进行 ...

  4. 【python】图像映射:单应性变换与图像扭曲

    [python]图像映射:单应性变换与图像扭曲 单应性变换(Homography) 图像扭曲(仿射变换) 图中图 分段仿射扭曲 单应性变换(Homography) 单应性变换(Homography)即 ...

  5. Python计算机视觉——图像到图像的映射

    Python计算机视觉--图像到图像的映射 文章目录 Python计算机视觉--图像到图像的映射 写在前面 1 单应性变换 1.1 直接线性变换算法 1.2 仿射变换 2 图像扭曲 2.1 图像中的图 ...

  6. 使用 Python 的图像隐写术

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 今天,世界正在见证前所未有的数据爆炸,我们每天产生的数据量确实令人 ...

  7. Python垂直翻转图像(Vertically Flip Image)

    Python垂直翻转图像(Vertically Flip Image) 目录 Python垂直翻转图像(Vertically Flip Image) #原始图像 #垂直图像翻转

  8. Python为图像添加文本内容(Writing Text on Image)

    Python为图像添加文本内容(Writing Text on Image) #原始图像 #图像添加文本 # from PIL import Image, ImageDraw, ImageFontim ...

  9. Python为图像添加水印(add watermark to an image)

    Python为图像添加水印(add watermark to an image) 目录 Python为图像添加水印(add watermark to an image) #原始图像

最新文章

  1. C中的qsort函数和C++中的sort函数的理解与使用
  2. Okhttp 使用与debug时留的大坑
  3. DAY02 WINDOWS Ghost系统的备份与还原以及不同虚拟机的通信的实现
  4. Python爬虫--抓取糗事百科段子
  5. k8s的资源限制及资源请求
  6. 力扣(Leetcode)-94. 二叉树的中序遍历
  7. 一段文字,写给合唱团即将分别的我们
  8. 【Linux】一步一步学Linux——mkdir命令(21)
  9. centos系统设置局域网静态IP
  10. [转]asp.net导出数据到Excel的三种方法
  11. Code Access Security (CAS)
  12. Real Vision CEO预测以太坊币价将在今年年初达到2万美元
  13. rust笔记9 错误处理
  14. 编程语言也有中年危机,Java 为何一直被唱衰?
  15. Java代码调用Shell脚本并传入参数实现DB2数据库表导出到文件
  16. JavaScript进阶讲解六—>js函数式编程
  17. 今晚7:30 | 连界、将门、百度、碧桂园创投四位大佬眼中的AI世界,是继续高深还是回归商业本质?...
  18. 荣耀6plus android版本号,荣耀6PLUS升级安卓6.0(emui4.0)感受
  19. VB读取武林外传内存地址
  20. 06 聚类算法 - 代码案例二 - K-Means算法和Mini Batch K-Means算法比较

热门文章

  1. 手机、平板的谷歌浏览器怎么设置电脑模式
  2. Dubbo系列之服务注册与发现
  3. 【微信小程序】JavaScript 从数组中删除指定值元素的方法封装
  4. 华南理工大学研究生宿舍一瞥
  5. Commons-beanutils
  6. html页面怎么实现背景全屏显示,HTML 全屏背景的方法
  7. linux mutt安装配置_linux mutt邮件发送配置
  8. mybatis-plus查询sql条件拼接deleted = 0
  9. 48 webpack优化-打包可视化
  10. Win10快捷键整理