Unbroken Developer
Unbroken Developer

Reputation: 3

how convert opencv c++ graycode->decode() function to cv2 python

In my project, I want to convert a C++ code from the opencv library into a Python code. My C++ code reference is below. https://docs.opencv.org/4.x/dc/da9/tutorial_decode_graycode_pattern.html In the C++ section, I came across a function that is as follows.

  Mat disparityMap;
  bool decoded = graycode->decode( captured_pattern, disparityMap, blackImages, whiteImages,
                                  structured_light::DECODE_3D_UNDERWORLD );

I converted half of this code to Python. However, I don't know if I went exactly right or not! I reached the decode section, but when I run the code, it gives this error.

Traceback (most recent call last): File "C:\Users\APA\Desktop\decode\decode.py", line 133, in decode = graycode.decode(images, blackImages=blackImages, whiteImages=whiteImages, flags=cv2.structured_light.DECODE_3D_UNDERWORLD) cv2.error: OpenCV(4.5.4) D:\a\opencv-python\opencv-python\opencv\modules\core\src\matrix.cpp:250: error: (-215:Assertion failed) s >= 0 in function 'cv::setSize'

I guess I made a mistake and confusion in assigning values ​​to the function arguments. That's why I have to post all the Python code so you can understand where I got the arguments from.

import cv2 
import numpy as np
import os
import natsort


def help():
      print("""------------ \nThis example shows how to use the \"Structured Light module\" to decode a previously acquired gray code pattern, generating a pointcloud"
        \nCall:\n
        ./example_structured_light_pointcloud <images_list> <calib_param_path> <proj_width> <proj_height> <white_thresh> <black_thresh>\n ------------"""
        )


width = 1280
height = 800

graycode = cv2.structured_light.GrayCodePattern_create( width, height   )
print(graycode)
print("-"* 40)

fs = cv2.FileStorage("calib.yml", cv2.FILE_STORAGE_READ)
cam1intrinsics = fs.getNode("cam1_intrinsics")
cam2intrinsics = fs.getNode("cam2_intrinsics")
cam1distCoeffs = fs.getNode("cam1_distorsion")
cam2distCoeffs = fs.getNode("cam2_distorsion")
R = fs.getNode("R")
T = fs.getNode("T")

print("cam1_intrinsics \n")
print(cam1intrinsics.mat())
print("cam2_intrinsics \n")
print(cam2intrinsics.mat())
print("cam1distCoeffs \n")
print(cam1distCoeffs.mat())
print("cam2distCoeffs \n")
print(cam2distCoeffs.mat())
print("R \n")
print(R.mat())
print("T \n")
print(T.mat())

print("--------- graycode numberOfPatternImages ----------")

numberOfPatternImages = graycode.getNumberOfPatternImages()
print(numberOfPatternImages)


print("--------- stereoRectify ----------")

def load_images_from_folder(folder):
    images = []
    for filename in os.listdir(folder):
        img = os.path.join(folder,filename)
        if img is not None and "pattern" in img:
            images.append(img)
    return  images

def png_counter(path):
  # folder path
  dir_path = path
  count = 0
  # Iterate directory
  for path in os.listdir(dir_path):
      # check if current path is a file
      if os.path.isfile(os.path.join(dir_path, path)):
          count += 1
  return count


unsort_imagelist_left  = load_images_from_folder("data1\\")
unsort_imagelist_right = load_images_from_folder("data2\\")

imagelist_left  = natsort.natsorted(unsort_imagelist_left,reverse=False)
imagelist_right = natsort.natsorted(unsort_imagelist_right,reverse=False)

color = cv2.imread( imagelist_left[numberOfPatternImages], cv2.IMREAD_COLOR)
height, width, channels = color.shape
imagesSize = (width, height)

R1 = np.zeros(shape=(3,3))
R2 = np.zeros(shape=(3,3))
P1 = np.zeros(shape=(3,3))
P2 = np.zeros(shape=(3,3))

cv2.stereoRectify(cam1intrinsics.mat(), cam1distCoeffs.mat(), cam2intrinsics.mat(), cam2distCoeffs.mat(), imagesSize, R.mat(), T.mat(), R1, R2, P1, P2, Q=None, alpha=-1, newImageSize=(0,0))

map1x, map1y = cv2.initUndistortRectifyMap(cam1intrinsics.mat(),  cam1distCoeffs.mat(), R1,  cam1intrinsics.mat(), imagesSize, cv2.CV_32FC1)
map2x, map2y = cv2.initUndistortRectifyMap(cam2intrinsics.mat(), cam2distCoeffs.mat(), R2, cam2intrinsics.mat(), imagesSize, cv2.CV_32FC1)

count_imagelist_left = png_counter("data1")
count_imagelist_right = png_counter("data2")


left_pattern = []
right_pattern = []

for i in range(0, numberOfPatternImages):
  left_pattern.append(cv2.imread(imagelist_left[i], cv2.IMREAD_GRAYSCALE))
  right_pattern.append(cv2.imread(imagelist_right[i], cv2.IMREAD_GRAYSCALE))

  cv2.remap(left_pattern[i], map1x, map1y, cv2.INTER_NEAREST, cv2.BORDER_CONSTANT)
  cv2.remap(right_pattern[i], map1x, map1y, cv2.INTER_NEAREST, cv2.BORDER_CONSTANT)

print("Remapimg Done !")

# data2\\pattern_cam2_im43.png
whiteImages = np.array(
  [cv2.cvtColor(color, cv2.COLOR_BGR2GRAY),
  cv2.imread(imagelist_right[numberOfPatternImages-1 + 1], cv2.IMREAD_GRAYSCALE)
  ])


# data/pattern_cam1_im44.png
blackImages =np.array( [
  cv2.imread(imagelist_left[numberOfPatternImages+1], cv2.IMREAD_GRAYSCALE),
  cv2.imread(imagelist_right[numberOfPatternImages+1], cv2.IMREAD_GRAYSCALE)
])


cv2.remap( color, map2x, map2y, cv2.INTER_NEAREST, cv2.BORDER_CONSTANT)
cv2.remap( whiteImages[0], map2x, map2y, cv2.INTER_NEAREST, cv2.BORDER_CONSTANT)
cv2.remap( whiteImages[1], map1x, map1y, cv2.INTER_NEAREST, cv2.BORDER_CONSTANT)
cv2.remap( blackImages[0], map2x, map2y, cv2.INTER_NEAREST, cv2.BORDER_CONSTANT)
cv2.remap( blackImages[1] , map1x, map1y, cv2.INTER_NEAREST, cv2.BORDER_CONSTANT)

print("\n Decofing Pattern ... \n")
capture_pattern = imagelist_left + imagelist_right

images = np.array([np.array(right_pattern), np.array(left_pattern)]),



# Problem is here -> 
decode = graycode.decode(images, blackImages=blackImages ,whiteImages=whiteImages, flags=cv2.structured_light.DECODE_3D_UNDERWORLD)

I searched all over the world internet, but so far no one has been able to publicly convert this C++ function to Python function. I mean it can generate an example and explain its arguments and display its output.

Upvotes: 0

Views: 195

Answers (0)

Related Questions