Python 如何为这些';简单';图像?
TLDR: 需要帮助计算两个图形之间的重叠区域 因此,我尝试缝合这两幅图像:Python 如何为这些';简单';图像?,python,image-processing,graph,overlap,Python,Image Processing,Graph,Overlap,TLDR: 需要帮助计算两个图形之间的重叠区域 因此,我尝试缝合这两幅图像: 因为我知道我将要缝合的图像肯定来自同一个图像,我觉得我应该能够自己编写代码。对于我来说,使用像OpenCV这样的库来完成这项任务感觉有点过头了 我目前的想法是,我可以通过对每个图像执行以下步骤来简化此任务: 使用PIL加载图像 将图像转换为黑白(PIL图像模式“L”) [可选:通过肉眼检查将图像裁剪到重叠区域] 创建向量行\u和,它是每行的和 [可选:logrow\u sum,以减少我们正在处理的值的大小] 绘制行
因为我知道我将要缝合的图像肯定来自同一个图像,我觉得我应该能够自己编写代码。对于我来说,使用像OpenCV这样的库来完成这项任务感觉有点过头了 我目前的想法是,我可以通过对每个图像执行以下步骤来简化此任务:
行\u和
,它是每行的和row\u sum
,以减少我们正在处理的值的大小]import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
class Stitcher():
def combine_2(self, img1, img2):
# thr1, thr2 = self.get_cropped_bw(img1, 115, img2, 80)
thr1, thr2 = self.get_cropped_bw(img1, 0, img2, 0)
row_sum1 = np.log(thr1.sum(1))
row_sum2 = np.log(thr2.sum(1))
self.plot_4x4(thr1, thr2, row_sum1, row_sum2)
def get_cropped_bw(self, img1, img1_keep_from, img2, img2_keep_till):
im1 = Image.open(img1).convert("L")
im2 = Image.open(img2).convert("L")
data1 = (np.array(im1)[img1_keep_from:]
if img1_keep_from != 0 else np.array(im1))
data2 = (np.array(im2)[:img2_keep_till]
if img2_keep_till != 0 else np.array(im2))
return data1, data2
def plot_4x4(self, thr1, thr2, row_sum1, row_sum2):
fig, ax = plt.subplots(2, 2, sharey="row", constrained_layout=True)
ax[0, 0].imshow(thr1, cmap="Greys")
ax[0, 1].imshow(thr2, cmap="Greys")
ax[1, 0].plot(row_sum1, "k.")
ax[1, 1].plot(row_sum2, "r.")
ax[1, 0].set(
xlabel="Index Value",
ylabel="Row Sum",
)
plt.show()
imgs = (r"combine\imgs\test_image_part_1.jpg",
r"combine\imgs\test_image_part_2.jpg")
s = Stitcher()
s.combine_2(*imgs)
这给了我这个图表:(我已经在这些黄色框中添加了,以指示重叠区域。) 这正是我被困的地方。我想确切地找到:
我觉得这可能是一个问题,可以使用点积来找到两个图形之间的相似性?但是我想不出如何实现这一点。我从中得到了比我预期的更多的乐趣。我是用opencv写的,但那只是为了加载和显示图像。其他一切都是用numpy完成的,所以将其交换到PIL应该不会太困难 我在用蛮力匹配器。我还编写了一个随机启动hillclimber,它运行的时间要短得多,但我不能保证它会找到正确的答案,因为梯度空间不是平滑的。我不会把它包含在我的代码中,因为它很长而且很简陋,但是如果你真的需要时间效率,我可以稍后再添加它 我在图像中添加了随机作物和一些椒盐噪声来测试鲁棒性 蛮力匹配器的工作原理是,我们不知道两幅图像的哪个部分重叠,所以我们需要从左到右、从上到下将较小的图像卷积到较大的图像上。这意味着我们的搜索空间是:
horizontal = small_width + big_width
vertical = small_height + big_height
area = horizontal * vertical
这将随着图像大小的增加而快速增长。我通过给它一个更大的重叠点来激励算法,但它会因为重叠区域的颜色差异而丢失更多的点
下面是一些执行此程序的图片
导入cv2
将numpy作为np导入
随机输入
#随机剪边
def randCrop(图像,最大边距):
c=[random.randint(0,maxMargin)表示范围(4)];
返回图像[c[0]:-c[1],c[2]:-c[3];
#给图像添加噪声
def saltPepper(图像、minNoise、maxNoise):
h、 w=图像。形状;
randNum=random.randint(minNoise,maxNoise);
对于范围内的(随机数):
x=random.randint(0,w-1);
y=随机随机随机数(0,h-1);
image[y,x]=random.randint(0255);
返回图像;
#评估布局
def getScore(一,二):
#做原始减法
左=一-二;
右=二-一;
sub=np.最小值(左、右);
返回np.count_非零(sub);
#返回范围内的二维随机位置
def randPos(img,大_形):
th,tw=大_形;
h、 w=img.形状;
x=随机随机随机数(0,tw-w);
y=随机随机随机数(0,th-h);
返回[x,y];
#将小图像叠加到大图像上
def覆盖层(小、大、位置):
#打开
h、 w=小形状;
x、 y=位置;
#复制并放置
copy=big.copy();
复制[y:y+h,x:x+w]=小;
返回副本;
#计算重叠区域
def重叠(一、二、一、二):
#打开
h1,w1=一个形状;
h2,w2=两个形状;
x1,y1=位置1;
x2,y2=位置2;
#定边
l1=x1;
l2=x2;
r1=x1+w1;
r2=x2+w2;
t1=y1;
t2=y2;
b1=y1+h1;
b2=y2+h2;
#去
左=最大值(l1,l2);
右=最小值(r1,r2);
顶部=最大值(t1,t2);
底部=最小值(b1,b2);
返回[左、右、上、下];
#覆盖+getScore的包装器
def满分(一、二、一、二、空):
#检查位置
x、 y=位置2;
h、 w=两个形状;
th,tw=大的空形状;
如果y+h>th或x+w>tw或x<0或y<0:
返回-9999999;
#覆盖层
temp_one=叠加(一,大,空,位置);
temp_two=叠加(两个,大的为空,位置为二);
#重叠
l、 r,t,b=重叠(一,二,位置一,位置二);
温度=温度[t:b,l:r];
温度二=温度二[t:b,l:r];
#得分
差异=得分(一级、二级);
得分=(r-l)*(b-t);
分数-=diff*2;
返回分数;
#使用暴力
def bruteForce(一,二):
#计算搜索空间
#开箱尺寸
h、 w=一个形状;
一个尺寸=h*w;
h、 w=两个形状;
两个_尺寸=h*w;
#大大小小
如果一个尺寸<两个尺寸:
小=一;
大=两个;
其他:
小=两个;
大=一;
#开箱尺寸
sh,sw=小的形状;
bh,bw=big.shape;
总宽度=bw+sw*2;
总高度=bh+sh*2;
#设置空图像
空=np.0((总高度,总宽度),np.uint8);
#创全球最佳
最佳得分=-999999;
最佳位置=无;
#开始滚动
伊布