VisionLabs/torch-opencv

Why using opencv cuda wrapper mess up all my tensors?

yxchng opened this issue · 2 comments

After using cuda to scale my img in function scale, i could not print the tensor anymore (note all the print statements in the code)

require 'paths'
paths.dofile('/home/iim/pose-hg-train/src/ref.lua')
paths.dofile('/home/iim/pose-hg-train/src/model.lua')

-- local cv = require 'cv'
require 'cutorch'
cv = require 'cv'
require 'cv.cudawarping'
require 'cv.highgui'
require 'cv.imgcodecs'

require 'cv.highgui' -- GUI
require 'cv.videoio' -- Video stream
require 'cv.imgproc' -- Image processing (resize, crop, draw text, ...)
require 'nn'

local function scale(input, size)
    local h, w = input:size(1), input:size(2)

    -- if (w <= h and w == size) or (h <= w and h == size) then
    --    return input
    -- end
    local inputCUDA = input:float():cuda() / 255
    if w < h then
        return cv.cuda.resize{inputCUDA, {w/h * size, size}}:float()
     else
        return cv.cuda.resize{inputCUDA, {size, h/w * size}}:float()
     end
end

local function padWithZeros(input, size)
    local output = torch.FloatTensor(size, size, 3)
    local w, h = input:size(2), input:size(1)
    local x, y = math.ceil((size-h)/2), math.ceil((size-w)/2)
    output:sub(x+1,x+h,y+1,y+w,1,3):copy(input:float())
    print(output)
    return output
end

local function getBoundingBox(bbox, rawImage)
    -- print(bbox)
    local boundingBox = rawImage:sub(bbox[2], bbox[2]+bbox[4], bbox[1], bbox[1]+bbox[3])
    return boundingBox

end

local function transformKpts(bbox, kpts)
    kpts:select(2,1):add(bbox[1])
    kpts:select(2,2):add(bbox[2])
    return kpts
end

local function detect_pose(bbox, rawImage)


    input = getBoundingBox(bbox, rawImage)
    input = scale(input, 256)
    input = padWithZeros(input, 256)
    input = input:reshape(3, 256, 256)
    print(input:size())
    -- print(input:size())
    -- print(input:float())
    -- print(input[0])
    print(input)
    if opt.GPU ~= -1 then
        -- Convert to CUDA
        cudaImg = applyFn(function (x) return x:cuda() end, input)
    end

    print(cudaImg:float())
    print ("foward")
    local hms = model:forward(cudaImg)[8][1]

    print("DONE INFERENCING")
    hms = hms:float()
    _, x = hms:max(2):max(3)
    MAX, y = hms:max(3):max(2)
    kpts = x:float():cat(y:float()):view(16,2):div(64):mul(256)
    score = MAX:float():view(16)

    print("DRAWING")
    imgWithSkeleton = drawSkeleton(rawImage:clone(), transformKpts(bbox, kpts), score)

    -- local hmImg
    -- local nOut,res = hms:size(1),hms:size(3)

    -- -- Repeat input image, and darken it to overlay heatmaps
    -- tmpInp = image.scale(img, res):mul(1)

    -- hmImg = tmpInp:repeatTensor(nOut,1,1,1)
    -- -- Copy ground truth heatmaps to red channel

    -- hmImg:sub(1,-1,1,1):add(hms:mul(1.3))
    -- -- -- Rescale so it is a little easier to see
    -- hmImg = image.scale(hmImg:view(nOut*3,res,res),256):view(nOut,3,256,256)
    return imgWithSkeleton

end


local capture = cv.VideoCapture{'/home/iim/pose-hg-train/src/test/data/test_video.avi'}
-- local capture = cv.VideoCapture{"/Users/yxchng/Desktop/pose_detection/test.mp4"}
local f = io.open('/home/iim/pose-hg-train/src/test/data/box.txt')

-- while true do
--     local ret, frame = capture:read{}
    
--     -- if not ret then
--     -- 	break 
--     -- end

--     local s = f:read()

--     -- print(frame)
--     -- if s ==  "" then
--     -- 	break
--     -- end
--     s = s:split(" ")
--     -- print(s)
--     -- print(x)
--     local x, y, w, h = tonumber(s[1]), tonumber(s[2]), tonumber(s[3]), tonumber(s[4])
--     -- local boundingBox = getBoundingBox({x,y,w,h}, frame)
--     local pose = detect_pose({x,y,w,h}, frame)
--     cv.Rect{tonumber(s[1]), tonumber(s[2]), tonumber(s[3]), tonumber(s[4])}
--     cv.rectangle{frame, {x, y}, {x+w, y+h}, color={255,0,255,0}}
--     cv.namedWindow{"video_img", 0}
--     -- cv.resizeWindow{"video_img", 500, 500};
--     cv.imshow{'video_img', pose}
--     cv.waitKey{1}
-- end


local ret, frame = capture:read{}

-- if not ret then
--  break 
-- end

local s = f:read()

-- print(frame)
-- if s ==  "" then
--  break
-- end
s = s:split(" ")
-- print(s)
-- print(x)
local x, y, w, h = tonumber(s[1]), tonumber(s[2]), tonumber(s[3]), tonumber(s[4])
-- local boundingBox = getBoundingBox({x,y,w,h}, frame)
local pose = detect_pose({x,y,w,h}, frame)
cv.Rect{tonumber(s[1]), tonumber(s[2]), tonumber(s[3]), tonumber(s[4])}
cv.rectangle{frame, {x, y}, {x+w, y+h}, color={255,0,255,0}}
cv.namedWindow{"video_img", 0}
-- cv.resizeWindow{"video_img", 500, 500};
cv.imshow{'video_img', pose}
cv.waitKey{1}

After using cuda to scale my img in function scale, i could not print the tensor anymore (not all the print statements in the code)

It gives the following error

THCudaCheck FAIL file=/home/iim/torch/extra/cutorch/lib/THC/generic/THCStorage.c line=182 error=17 : invalid device pointer
/home/iim/torch/install/bin/luajit: cuda runtime error (17) : invalid device pointer at /home/iim/torch/extra/cutorch/lib/THC/generic/THCStorage.c:182

I suspect it has something to do with the tensor being on the GPU rather than CPU. If that is the case, how do I turn it back into normal tensor on the CPU?

Hi, thanks for reporting. I know there are lots of issues with OpenCV CUDA interface, people often complain about it. Unfortunately, I've lost access to GPU and still don't have one. So this interface is now very unstable, I hope to get to it back soon but not sure when, sorry for that. Please use CPU for now.