- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一张图像,其高度/宽度尺寸分别为 3837x5126 像素。
我的目标是将此图像分成具有 1000x1000 像素精确尺寸的独立图 block 。如果图像不能被均匀分割,则应创建重叠图 block ,使图 block 均为 1000x1000 像素。
这是在 PowerPoint 中创建的粗略可视化,用于说明我正在尝试做的事情:
我的思考过程是这样的:
这是我到目前为止的代码。
import numpy as np
def get_divisions(num, divisor):
n = num / divisor
divisions = math.floor(n)
remainder = n % 1
offset = remainder / divisions
return divisions, offset
def get_tiles(height, width, window_size=1000):
number_of_rows, row_offset = get_divisions(height, window_size)
number_of_columns, col_offet = get_divisions(width, window_size)
tiles = []
for row in range(number_of_rows):
for col in range(number_of_columns):
if row == 0:
row_offset = 0
if col == 0:
col_offset = 0
x = (col * window_size) - (col_offset * window_size)
y = (row * window_size) - (row_offset * window_size)
w = window_size
h = window_size
tiles.append([x, y, h, w])
return np.array(tiles, dtype="uint32")
height = 3837
width = 5126
get_tiles(height, width)
输出:
array([[ 0, 0, 1000, 1000],
[1000, 0, 1000, 1000],
[2000, 0, 1000, 1000],
[3000, 0, 1000, 1000],
[4000, 0, 1000, 1000],
[ 0, 1000, 1000, 1000],
[1000, 1000, 1000, 1000],
[2000, 1000, 1000, 1000],
[3000, 1000, 1000, 1000],
[4000, 1000, 1000, 1000],
[ 0, 2000, 1000, 1000],
[1000, 2000, 1000, 1000],
[2000, 2000, 1000, 1000],
[3000, 2000, 1000, 1000],
[4000, 2000, 1000, 1000]], dtype=uint32)
如您所见,我的 [x, y, h, w]
矩阵不正确,因为有一些 x,y 点位于 3837x5126 像素图像之外。
如有任何帮助,我们将不胜感激!
这里是 answer @HansHirse gave添加了一些测试。
import unittest
import math
import numpy as np
def tile(h, w, tile_width=None, tile_height=None, window_size=100):
np.seterr(divide='ignore', invalid='ignore')
if not tile_width:
tile_width = window_size
if not tile_height:
tile_height = window_size
wTile = tile_width
hTile = tile_height
if tile_width > w or tile_height > h:
raise ValueError("tile dimensions cannot be larger than origin dimensions")
# Number of tiles
nTilesX = np.uint8(np.ceil(w / wTile))
nTilesY = np.uint8(np.ceil(h / hTile))
# Total remainders
remainderX = nTilesX * wTile - w
remainderY = nTilesY * hTile - h
# Set up remainders per tile
remaindersX = np.ones((nTilesX-1, 1)) * np.uint16(np.floor(remainderX / (nTilesX-1)))
remaindersY = np.ones((nTilesY-1, 1)) * np.uint16(np.floor(remainderY / (nTilesY-1)))
remaindersX[0:np.remainder(remainderX, np.uint16(nTilesX-1))] += 1
remaindersY[0:np.remainder(remainderY, np.uint16(nTilesY-1))] += 1
# Initialize array of tile boxes
tiles = np.zeros((nTilesX * nTilesY, 4), np.uint16)
k = 0
x = 0
for i in range(nTilesX):
y = 0
for j in range(nTilesY):
tiles[k, :] = (x, y, hTile, wTile)
k += 1
if j < (nTilesY-1):
y = y + hTile - remaindersY[j]
if i < (nTilesX-1):
x = x + wTile - remaindersX[i]
return tiles
class TestTilingWithoutRemainders(unittest.TestCase):
def test_it_returns_tiles_without_overflow(self):
self.assertEqual(tile(500, 500, window_size=500).tolist(), np.array([[0, 0, 500, 500]], dtype="uint16").tolist())
self.assertEqual(tile(250, 500, window_size=250).tolist(), np.array(
[[0, 0, 250, 250], [250, 0, 250, 250]], dtype="uint16"
).tolist())
self.assertEqual(tile(500, 250, window_size=250).tolist(), np.array(
[[0, 0, 250, 250], [0, 250, 250, 250]], dtype="uint16"
).tolist())
class TestTilingWithRemainders(unittest.TestCase):
def test_it_returns_tiles_with_overflow(self):
self.assertEqual(tile(500, 501, window_size=500).tolist(), np.array(
[[0, 0, 500, 500], [1, 0, 500, 500]], dtype="uint16"
).tolist())
self.assertEqual(tile(251, 250, window_size=250).tolist(), np.array(
[[0, 0, 250, 250], [0, 1, 250, 250]], dtype="uint16"
).tolist())
class TestTilingWithInvalidWindowSizes(unittest.TestCase):
def test_it_raises_an_error_with_invalid_tile_height(self):
self.assertRaises(ValueError, tile, 500, 500, tile_height=50000000)
def test_it_raises_an_error_with_invalid_tile_width(self):
self.assertRaises(ValueError, tile, 500, 500, tile_width=50000000)
def test_it_raises_an_error_with_invalid_window_size(self):
self.assertRaises(ValueError, tile, 500, 500, window_size=50000000)
最佳答案
这是我的解决方案。不幸的是,我的代码不是基于您的代码,但我希望您仍然可以遵循它。主要方法与您在问题中描述的完全相同。
让我们看一下代码:
import cv2
import numpy as np
# Some image; get width and height
image = cv2.resize(cv2.imread('path/to/your/image.png'), (512, 383))
h, w = image.shape[:2]
# Tile parameters
wTile = 100
hTile = 100
# Number of tiles
nTilesX = np.uint8(np.ceil(w / wTile))
nTilesY = np.uint8(np.ceil(h / hTile))
# Total remainders
remainderX = nTilesX * wTile - w
remainderY = nTilesY * hTile - h
# Set up remainders per tile
remaindersX = np.ones((nTilesX-1, 1)) * np.uint16(np.floor(remainderX / (nTilesX-1)))
remaindersY = np.ones((nTilesY-1, 1)) * np.uint16(np.floor(remainderY / (nTilesY-1)))
remaindersX[0:np.remainder(remainderX, np.uint16(nTilesX-1))] += 1
remaindersY[0:np.remainder(remainderY, np.uint16(nTilesY-1))] += 1
# Initialize array of tile boxes
tiles = np.zeros((nTilesX * nTilesY, 4), np.uint16)
# Determine proper tile boxes
k = 0
x = 0
for i in range(nTilesX):
y = 0
for j in range(nTilesY):
tiles[k, :] = (x, y, hTile, wTile)
k += 1
if (j < (nTilesY-1)):
y = y + hTile - remaindersY[j]
if (i < (nTilesX-1)):
x = x + wTile - remaindersX[i]
print(tiles)
对于尺寸为 [512, 383]
且拼贴大小为 [100, 100]
的图像,tiles
数组如下所示:
[[ 0 0 100 100]
[ 0 94 100 100]
[ 0 188 100 100]
[ 0 283 100 100]
[ 82 0 100 100]
[ 82 94 100 100]
[ 82 188 100 100]
[ 82 283 100 100]
[164 0 100 100]
[164 94 100 100]
[164 188 100 100]
[164 283 100 100]
[246 0 100 100]
[246 94 100 100]
[246 188 100 100]
[246 283 100 100]
[329 0 100 100]
[329 94 100 100]
[329 188 100 100]
[329 283 100 100]
[412 0 100 100]
[412 94 100 100]
[412 188 100 100]
[412 283 100 100]]
您将获得 24 个图 block ,每个图 block 的大小为 [100, 100]
,并且尽可能有最相似的重叠。
如果我们切换到尺寸为 [500, 300]
的图像,我们会得到这些 tiles
:
[[ 0 0 100 100]
[ 0 100 100 100]
[ 0 200 100 100]
[100 0 100 100]
[100 100 100 100]
[100 200 100 100]
[200 0 100 100]
[200 100 100 100]
[200 200 100 100]
[300 0 100 100]
[300 100 100 100]
[300 200 100 100]
[400 0 100 100]
[400 100 100 100]
[400 200 100 100]]
如您所见,只剩下 15 个图 block ,并且完全没有重叠。
希望对您有所帮助!
关于python - 如何将图像分成大小均匀、需要时重叠的图 block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58383814/
我需要在半径R的圆内生成一个均匀随机点。 我意识到,通过在区间 [0 ... 2π) 中选择均匀随机的角度,并在区间 (0 ... R) 中选择均匀随机的半径,我最终会得到更多的点朝向中心,因为对于两
我想在一个正方形内生成 N 个点(均匀地)。我怎样才能做到这一点? 最佳答案 非常酷的问题,比我想象的要困难得多,但这就是想法。有关于 n 边形的论文,但我只会做正方形。因此,圆的均匀分布是一个常见问
考虑以下示例: import itertools import numpy as np a = np.arange(0,5) b = np.arange(0,3) c = np.arange(0,7)
SQL Server 将一组值分成 5 组,每组的 sum(count) 应该均匀分布。 表仅包含 2 列 rid 和 count。 create table t1(rid int, count in
我有以下简单的 HTML。 A B C 和 CSS: ul { width: 100%; display: flex; flex-direction:
我是一名优秀的程序员,十分优秀!