1、
PyraNete测试的时候是怎么将坐标对应到原来的图像上的呢?????
local function getHeatmaps(imHeight, imWidth, center, scale, rot, res, hm)
local ul = t.transform({1,1}, center, scale, 0, res, true)
local br = t.transform({res,res}, center, scale, 0, res, true)
newDim = torch.IntTensor({3, br[2] - ul[2], br[1] - ul[1]}) -- 和训练时的套路一样,看看对应到原图怎样去剪切才能将整个人包住
ht = imHeight
wd = imWidth
local newX = torch.Tensor({math.max(1, -ul[1]+1), math.min(br[1], wd) - ul[1]})
local newY = torch.Tensor({math.max(1, -ul[2]+1), math.min(br[2], ht) - ul[2]})
local oldX = torch.Tensor({math.max(1, ul[1]+1), math.min(br[1], wd)})
local oldY = torch.Tensor({math.max(1, ul[2]+1), math.min(br[2], ht)}) -- 定义旧图像代表的范围和新图像代表的范围,类似训练
local newHm = torch.zeros(hm:size(1), ht, wd) --newHm的大小是原来的图像的大小
hm = image.scale(hm:float(), newDim[3], newDim[2]) --hm是预测出来的64*64的featuremap
newHm:sub(1, hm:size(1), oldY[1],oldY[2],oldX[1],oldX[2]):copy(hm:sub(1,hm:size(1),newY[1],newY[2],newX[1],newX[2])) 将newHm对应的有该人的区域复制成此人
返回newHm
进入multitest的主程序里面
finalPredsHms = output[#output]
fuseHm = torch.zeros(self.opt.nClasses, imHeight, imWidth)
for pyra = 1, #scales do
local hm_img = getHeatmaps(imHeight, imWidth, sample.center[pyra], sample.scale[pyra], 0, 256, finalPredsHms[pyra])
fuseHm = fuseHm + hm_img
end
fuseHm = fuseHm/#scales
上面的这个程序就是将预测出来的featuremap映射回原图中,这样直接在原图中取最大最小值就是我们要求得预测的坐标值
会担心不同尺度裁剪出来的区域都是不一样的,这样做平均是不是不合理?不是这样的,因为center和scale也会发生相应的变化,所以不会存在这样的问题,最后是可以相加的
那么hourglass在做test预测的时候是怎么实现的呢??
saved.idxs:sub(tmpIdx, tmpIdx+bs-1):copy(indices)
saved.preds:sub(tmpIdx, tmpIdx+bs-1):copy(postprocess(set,indices,output))
重点是postprocess这个函数
function postprocess(set, idx, output)
local tmpOutput
if type(output) == 'table' then tmpOutput = output[#output]
else tmpOutput = output end
local p = getPreds(tmpOutput) --获得输出 bxcx2
local scores = torch.zeros(p:size(1),p:size(2),1) --定义每个预测的分数
-- Very simple post-processing step to improve performance at tight PCK thresholds
for i = 1,p:size(1) do
for j = 1,p:size(2) do
local hm = tmpOutput[i][j]
local pX,pY = p[i][j][1], p[i][j][2]
scores[i][j] = hm[pY][pX]
if pX > 1 and pX < opt.outputRes and pY > 1 and pY < opt.outputRes then
local diff = torch.Tensor({hm[pY][pX+1]-hm[pY][pX-1], hm[pY+1][pX]-hm[pY-1][pX]})
p[i][j]:add(diff:sign():mul(.25))
end
end
end
p:add(0.5) --以上部分是对预测出来的坐标点做一个更加精准的回归
-- Transform predictions back to original coordinate space
local p_tf = torch.zeros(p:size())
for i = 1,p:size(1) do
_,c,s = dataset:getPartInfo(idx[i])
p_tf[i]:copy(transformPreds(p[i], c, s, opt.outputRes)) --这个函数才是真正的将坐标点映射到原来的图像中的函数
end
return p_tf:cat(p,3):cat(scores,3)
end
function transformPreds(coords, center, scale, res)
local origDims = coords:size()
coords = coords:view(-1,2)
local newCoords = coords:clone()
for i = 1,coords:size(1) do
newCoords[i] = transform(coords[i], center, scale, 0, res, 1) --有了c,s就会将图像变换到原来的对应图像中的位置了,关键在这一步了
end
return newCoords:view(origDims)
end