最近在做DL定位Gaze的东西,因为网络是单独对左眼和右眼的图片进行训练的,但是拿到的数据集是MPIIGaze的公开数据集,里面的图片都是一整张人眼的图片,为了把左眼和右眼单独分开,决定对图片一半进行裁剪,但是图片周围都有黑框,黑框的大小也是不确定的,这样就造成了图片切割一半可能很多左眼和右眼分割不太好的情况,见图!
这张图切割以后左眼就少了一点点,这样也会对网络的训练有非常大的影响。所以必须想办法把图片周围的黑色边框给去掉。本来以为这么简单的东西网上应该都会有很多现成方法可以用的,结果找了半天居然么得,最后自己想了个法子,顺便写个博客当作笔记好了。
随便给一张数据集中的人眼图片:
当时想了几个办法:
1)遍历整个像素矩阵,把像素点rgb之和不为0的点存下来,这种方法是最准确的,但是整个图片是720*1620的,整个数据集21W+的图片量,估计遍历几辈子过去了。
2)如果从左上角开始逐渐向内延伸,碰到第一个像素点rgb之和不为0的点即记住横纵坐标,右下角的定位也一样,这种方法还是可以取的,但是有个问题就是很多眼睛图片并不在整张图片的正中间,而且图片不是正方形,所以对很多图片不可用。
3)这次想的方法还可,先把整个彩色图片的矩阵,每个点的rgb值相加,保存在一个矩阵A中,再找到A中最大值所在的位置,根据这个位置的横纵坐标,从上下左右分别从图片边缘向内靠近,直到像素点rgb之和不为0的点,并记录位置。如图:
假设图中红点是rgb之和最大的点(随便取的一个点),那这个点坐标(x,y)的值确定以后,如图:
像这样从两边向图片靠近,最后效果还是蛮不错的,但是也仅适用于图片是矩形的情况。
原图:
效果图:
我是MATLAB做的,代码如下:
a = imread(nm1); %读取图片
A=[];
for i=1:size(a,1)
for j=1:size(a,2)
A(i,j)=sum(a(i,j,:));
end
end
[ss,zz]=find(A==max(max(A)));
z=1;
while(sum(a(ss,z,:))==0)
z=z+1;
end
y=size(a,2);
while(sum(a(ss,y,:))==0)
y=y-1;
end
s=1;
while(sum(a(s,zz,:))==0)
s=s+1;
end
x=size(a,1);
while(sum(a(x,zz,:))==0)
x=x-1;
end
aa=a(s:x,z:y,:);
imshow(aa);
————————————————————————————————————————————————————————————————————————————————————————————————————————————————
一周后......
由于老师的服务器上没有matlab,Linux装起来又比较麻烦,只能把代码又换成python了,第一次写python,快崩溃了,简单给矩阵赋个值都会出错,各种搜百度,matlab遇到问题一搜一大片,感觉python搜起来想找到解决方案好麻烦,而且用起来也不如matlab方便,搞了几个小时以后总算写出来了,乱七八糟的库一起用,这次顺便把图片的尺寸也一起resize了一下。
看了一下,处理速度也没有matlab快,内心一阵mmp......
python代码如下:
import os
import numpy as np
from PIL import Image
import cv2
import matplotlib.pyplot as plt
rootdir = './Original';
rootdir33 = './CLH1';
list = os.listdir(rootdir); #列出文件夹下所有的目录与文件
for i in range(0,len(list)):
#for i in range(0,1):
parts=[];
parts=[rootdir,'/',list[i]];
root=''.join(parts);
parts=[];
parts=[rootdir33,'/',list[i]];
root33=''.join(parts);
list1 = os.listdir(root);
for j in range(1,len(list1)):
parts=[];
parts=[root,'/',list1[j]];
root1=''.join(parts);
parts=[];
parts=[root33,'/',list1[j]];
root44=''.join(parts);
list2 = os.listdir(root1);
for k in range(0,len(list2)-1):
parts=[];
parts=[root1,'/',list2[k]];
root2=''.join(parts);
A1=cv2.imread(root2)
h = A1.shape[0] #图像的高度(行 范围)
w = A1.shape[1]
A=np.array(A1)
B=np.zeros((h,w));
for m in range(h):
for n in range(w):
B[m][n]=int(A[m][n][0])+int(A[m][n][1])+int(A[m][n][2])
c=np.where(B==np.amax(B))
w1=c[0][0]
w2=c[1][0]
z=0;y=w-1;s=0;x=h-1;
while(B[w1,z]==0):
z=z+1;
while(B[w1,y]==0):
y=y-1;
while(B[s,w2]==0):
s=s+1;
while(B[x,w2]==0):
x=x-1;
#im=A1[s:x,z:y]
imy = A1[s:x,z:z+round((y-z)/2)]
imz = A1[s:x,z+round((y-z)/2):y]
#cv2.imshow('input_image',im)
#cv2.imshow('input_image',imz)
#cv2.imshow('input_image',imy)
#对图片大小进行resize
crop_size = (36,60)
imz = cv2.resize(imz, crop_size, interpolation = cv2.INTER_CUBIC)
imy = cv2.resize(imy, crop_size, interpolation = cv2.INTER_CUBIC)
####保存左眼
parts=[]
parts=[root44,'/z'];
rootzz=''.join(parts);
if bool(1-os.path.exists(rootzz)):
os.makedirs(rootzz)
parts=[rootzz,'/',list2[k]];
rootz=''.join(parts);
cv2.imwrite(rootz,imz) #保存图片
####保存右眼
parts=[]
parts=[root44,'/y'];
rootyy=''.join(parts);
if bool(1-os.path.exists(rootyy)):
os.makedirs(rootyy);
parts=[rootyy,'/',list2[k]];
rooty=''.join(parts);
cv2.imwrite(rooty,imy) #保存图片