OpenGL 2.1/4.1(GLFW)でOpenCVの画像を表示する(Python, Mac)

pip3 install PyOpenGL glfw モジュールバージョン PyOpenGL==3.1.5 glfw==1.11.0 システムのOpenGLバージョン Vendor : b'Intel Inc.' GPU : b'Intel Iris OpenGL Engine' OpenGL version : b'4.1 INTEL-14.4.23' OpenGL 2.1 mcfletch/pyopengl: Repository for the PyOpenGL Project Python3で始めるOpenGL4 - CodeLabo Python GLFWでOpenGLバージョン指定とウィンドウ表示 - CodeLabo PythonでOpenCVの画像をOpenGLで表示する - Qiita Vendor : b'Intel Inc.' GPU : b'Intel Iris OpenGL Engine' OpenGL version : b'2.1 INTEL-14.4.23' glDrawPixels import cv2 from OpenGL.GL import * import glfw if __name__ == '__main__': img = cv2.imread('lena.png', 1) img_gl = cv2.cvtColor(cv2.flip(img, 0), cv2.COLOR_BGR2RGB) glfw.init() # These parameters need to be changed according to your environment. # Mac: https://support.apple.com/ja-jp/HT202823 # glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4) # glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 1) # glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, True) # glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) width = img.shape[1] height = img.shape[0] window = glfw.create_window(width, height, 'Lena', None, None) glfw.make_context_current(window) print('Vendor :', glGetString(GL_VENDOR)) print('GPU :', glGetString(GL_RENDERER)) print('OpenGL version :', glGetString(GL_VERSION)) while not glfw.window_should_close(window): glClearColor(0, 0, 0, 1) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glDrawPixels(width, height, GL_RGB, GL_UNSIGNED_BYTE, img_gl) glfw.swap_buffers(window) glfw.poll_events() glfw.destroy_window(window) glfw.terminate() Texture import cv2 from OpenGL.GL import * import glfw if __name__ == '__main__': img = cv2.imread('lena.png', 1) img_gl = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) glfw.init() # These parameters need to be changed according to your environment. # Mac: https://support.apple.com/ja-jp/HT202823 # glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4) # glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 1) # glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, True) # glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) window = glfw.create_window(256, 256, 'Lena', None, None) glfw.make_context_current(window) print('Vendor :', glGetString(GL_VENDOR)) print('GPU :', glGetString(GL_RENDERER)) print('OpenGL version :', glGetString(GL_VERSION)) height, width = img.shape[:2] glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, img_gl) while not glfw.window_should_close(window): glClearColor(0, 0, 0, 1) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glEnable(GL_TEXTURE_2D) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glBegin(GL_QUADS) glTexCoord2d(0.0, 1.0) glVertex3d(-1.0, -1.0, 0.0) glTexCoord2d(1.0, 1.0) glVertex3d(1.0, -1.0, 0.0) glTexCoord2d(1.0, 0.0) glVertex3d(1.0, 1.0, 0.0) glTexCoord2d(0.0, 0.0) glVertex3d(-1.0, 1.0, 0.0) glEnd() glfw.swap_buffers(window) glfw.poll_events() glfw.destroy_window(window) glfw.terminate() OpenGL 4.1 / GLSL PythonでVAOによるGLSLシェーダープログラミング! - CodeLabo Suspected fragment shader problem, No color, OpenGL 4, GLFW 3, GLEW - OpenGL / OpenGL: Basic Coding - Khronos Forums 床井研究室 - 第2回 テクスチャの割り当て Vendor : b'Intel Inc.' GPU : b'Intel Iris OpenGL Engine' OpenGL version : b'4.1 INTEL-14.4.23' import sys from OpenGL.GL import * import glfw import numpy as np import cv2 vertex_shader_text = ''' #version 410 core in vec3 vPosition; out vec2 vTextureCoord; void main(void) { vTextureCoord = vec2((vPosition.x + 1.0) / 2, (vPosition.y + 1.0) / 2); gl_Position = vec4(vPosition, 1.0); } ''' fragment_shader_text = ''' #version 410 core uniform sampler2D vTexture; in vec2 vTextureCoord; out vec4 flagColor; void main(void) { flagColor = texture(vTexture, vTextureCoord).rgba; } ''' def init_context(): print('Initializing context..') glfw.init() glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4) glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 1) glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, True) glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) global window window = glfw.create_window(512, 512, __file__, None, None) glfw.make_context_current(window) print('Vendor :', glGetString(GL_VENDOR)) print('GPU :', glGetString(GL_RENDERER)) print('OpenGL version :', glGetString(GL_VERSION)) def init_texture(): print('Initializing texture..') img = cv2.imread('lena.png', 1) img_gl = cv2.cvtColor(cv2.flip(img, 0), cv2.COLOR_BGR2RGB) global width, height height, width = img.shape[:2] global texture texture = glGenTextures(1) glActiveTexture(GL_TEXTURE0) glBindTexture(GL_TEXTURE_2D, texture) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glPixelStorei(GL_UNPACK_ALIGNMENT, 1) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, img_gl) def init_shader(): print('Initializing shader..') global vertex_shader vertex_shader = glCreateShader(GL_VERTEX_SHADER) glShaderSource(vertex_shader, vertex_shader_text) glCompileShader(vertex_shader) if not glGetShaderiv(vertex_shader, GL_COMPILE_STATUS): print('Vertex shader is not OK') print(glGetShaderInfoLog(vertex_shader)) sys.exit(1) else: print('Vertex shader is OK') global fragment_shader fragment_shader = glCreateShader(GL_FRAGMENT_SHADER) glShaderSource(fragment_shader, fragment_shader_text) glCompileShader(fragment_shader) if not glGetShaderiv(fragment_shader, GL_COMPILE_STATUS): print('Fragment shader is not OK') print(glGetShaderInfoLog(fragment_shader)) sys.exit(1) else: print('Fragment shader is OK') global program program = glCreateProgram() glAttachShader(program, vertex_shader) glDeleteShader(vertex_shader) glAttachShader(program, fragment_shader) glDeleteShader(fragment_shader) glLinkProgram(program) if not glGetProgramiv(program, GL_LINK_STATUS): print('Shader program is not OK') print(glGetProgramInfoLog(program)) sys.exit(1) else: print('Shader program is OK') def init_vao(): print('Initializing vao..') # anti-clockwise vertices = np.array([ -1.0, -1.0, 0.0, # left bottom 1.0, -1.0, 0.0, # right bottom -1.0, 1.0, 0.0, # left top -1.0, 1.0, 0.0, # left top 1.0, -1.0, 0.0, # right bottom 1.0, 1.0, 0.0, # right top ], dtype=np.float32) global vertex_vbo vertex_vbo = glGenBuffers(1) global vertex_vao vertex_vao = glGenVertexArrays(1) glBindVertexArray(vertex_vao) glEnableVertexAttribArray(0) glBindBuffer(GL_ARRAY_BUFFER, vertex_vbo) glBufferData(GL_ARRAY_BUFFER, vertices.nbytes, vertices, GL_STATIC_DRAW) glVertexAttribPointer(0, 3, GL_FLOAT, False, 0, None) glBindVertexArray(0) def render(): glUseProgram(program) glUniform1i(glGetUniformLocation(program, 'vTexture'), 0) glBindVertexArray(vertex_vao) glDrawArrays(GL_TRIANGLES, 0, 6) glBindVertexArray(0) if __name__ == '__main__': init_context() init_texture() init_shader() init_vao() print('Start rendering..') while not glfw.window_should_close(window): glClearColor(0, 0, 0, 1) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) render() glfw.swap_buffers(window) glfw.poll_events() glfw.destroy_window(window) glfw.terminate() PyOpenGL Documentation PyOpenGL · PyPI glfw · PyPI

2020年3月23日 · aoirint

Fisheye distortion

OpenCV: Camera Calibration and 3D Reconstruction OpenCV: Fisheye camera model 歪みなしカメラ画像の座標変換 - えやみぐさ カメラ座標 $$ P_c = \left( \begin{array}{c} X_c \ Y_c \ Z_c \end{array} \right) $$ $$ x’ = X_c / Z_c \ y’ = Y_c / Z_c \ r^2 = x’^2 + y’^2 \ \theta = {\rm atan}(r) $$ 歪み補正 / Distortion correction $$ \theta_d = \theta ( 1 + k_1 \theta^2 + k_2 \theta^4 + k_3 \theta^6 + k_4 \theta^8 )\ x’’ = \frac{ \theta_d }{r} x’ \ y’’ = \frac{ \theta_d }{r} y' $$ ...

2020年3月21日 · aoirint

Lens Distortion

OpenCV: Camera Calibration and 3D Reconstruction 歪みなしカメラ画像の座標変換 - えやみぐさ カメラ座標 $$ P_c = \left( \begin{array}{c} X_c \ Y_c \ Z_c \end{array} \right) $$ $$ x’ = X_c / Z_c \ y’ = Y_c / Z_c \ r^2 = x’^2 + y’^2 $$ 歪み補正 / Distortion correction $$ x’’ = x’ \frac{ 1 + k_1\ r^2 + k_2\ r^4 + k_3\ r^6 }{ 1 + k_4\ r^2 + k_5\ r^4 + k_6\ r^6 } + 2 p_1 x’ y’ + p_2 (r^2 + 2 x’^2) + s_1 r^2 + s_2 r^4 \ y’’ = y’ \frac{ 1 + k_1\ r^2 + k_2\ r^4 + k_3\ r^6 }{ 1 + k_4\ r^2 + k_5\ r^4 + k_6\ r^6 } + p_1 (r^2 + 2 y’^2) + 2 p_2 x’ y’ + s_1 r^2 + s_2 r^4 $$ ...

2020年3月21日 · aoirint

歪みなしカメラ画像の座標変換

OpenCV: Camera Calibration and 3D Reconstruction カメラ行列(内部パラメータ / intrinsic parameters) $$ A = \left( \begin{array}{ccc} f_x & 0 & c_x \ 0 & f_y & c_y \ 0 & 0 & 1 \end{array} \right) $$ 焦点距離 ( f_x, f_y ) 単位は画素(pixels) 2つの役割をもつ ピンホールカメラモデルにおける焦点距離(tex: f )(参考:ピンホールカメラモデル) 任意の単位で表される変換前の座標からコンピュータ上の画素の単位であるピクセル単位に変換する ピンホールカメラモデルでは1つの焦点距離(tex: f )しかなかったのに、なぜ(tex: f_x, f_y )と2つ含まれているのか 2つ目の役割(撮像素子の位置=実世界の距離からピクセル単位に変換)のため、撮像素子の特性(px/mm)がx、y方向で異なる場合を想定している(( f_x, f_y )はレンズの物理的な焦点距離 ( tex: f )(mm)と撮像素子の特性( c_x, c_y)の積。また、カメラ画像からそれぞれを独立に求めることはできない) 参考:computer vision - Why does the focal length in the camera intrinsics matrix have two dimensions? - Stack Overflow, Learning OpenCV 画像の中心 (c_x, c_y) 単位は画素(pixels) 射影変換行列(Perspective transform matrix, 外部パラメータ/ extrinsic parameters) 参考:2次元の射影変換行列 $$ [R|t] = \left( \begin{array}{cccc} r_{11} & r_{12} & r_{13} & t_x \ r_{21} & r_{22} & r_{23} & t_y \ \end{array} \right) $$ ...

2020年3月21日 · aoirint

ピンホールカメラモデル

Pinhole camera model - Wikipedia OpenCV: Camera Calibration and 3D Reconstruction 3次元空間をカメラで撮影したときの、「3次元空間(実世界)上の点の座標\((x, y, z)\)」と「2次元写真平面上の点の座標\((u, v)\)」の変換\((u, v) = T(x, y, z)\)を考える。 カメラの位置を3次元空間における原点\(O\)とする。 ここでカメラに固有なパラメータとして、焦点距離\(f (> 0)\)を導入する。焦点距離は、カメラ(原点\(O\))に入射した光が写真として実像を結ぶスクリーン(写真平面)までの距離である。この設定から、3次元空間上で写真平面(スクリーン)は\(z = -f\)にあるとわかる(写真平面をx-y平面と並行とし、z軸を3次元空間上の奥行きとする)。なお、\(f\)がより大きいカメラで撮影したとき、同じ距離にある被写体はより大きく写る(凸レンズ)。 (図はPinhole camera model - Wikipediaから引用。軸X1, X2, X3はx, y, zに、Y1, Y2はu, vに対応) 点P\((x, y, z)\)から原点Oを通過し、スクリーン上の点Q\((-u, -v, -f)\)に入射する光を考える。なお、実像は光軸を中心に上下左右に反転するため、このとき点Qは写真において座標\((u, v)\)にある。 点Pからxz平面上に落とした点P’\((x, 0, z)\)、点Qからxz平面上に落とした点Q’\((-u, 0, -f)\)を導入する。ここで、三角形POP’と三角形QOQ’は共通の角度を持つ相似な三角形である。この性質から、辺POと辺P’Oの長さの比\(x / z\)、辺QOと辺Q’Oの長さの比\((-u) / (-f)\)は等しい。すなわち、\(\frac{x}{z} = \frac{u}{f}\)。\(u\)について整理すると、\(u = f \frac{x}{z}\)。 (図はPinhole camera model - Wikipediaから引用。青線がスクリーン上の実像、赤線が実体。計算では図中の\(f\)を\(-f\)としている) ...

2020年3月21日 · aoirint