为什么我的图像在 OpenCV Python 中显示为灰色?
Why is my image appearing gray in OpenCV Python?
我正在从事一个项目,该项目由我的代码组成,用于识别数独谜题的图像,然后解决它。我现在正在研究图像识别部分。它工作正常,直到我意识到我一直在使整个程序在 y 轴上翻转。所以我更换了
dimensions = np.array([[0, 0], [width, 0], [width, height], [0, height]], dtype = "float32")
和
dimensions = np.array([[width, 0], [0, 0], [0, height], [width, height]], dtype = "float32")
这似乎改变了一切,现在我 运行 我只得到一张灰色图像。
这是我的代码。
请注意,我是 opencv 的新手。另外,我在我的代码中画线,当我 运行 它时,这些线仍然出现。只是实际图像没有出现。
#Imports
import cv2 as cv
import numpy as np
import math
#Load image
img = cv.imread('sudoku_test_image.jpeg')
#Transforms perspective
def perspectiveTransform(img, corners):
def orderCornerPoints(corners):
#Corners sperated into their own points
#Index 0 = top-right
# 1 = top-left
# 2 = bottom-left
# 3 = bottom-right
#Corners to points
corners = [(corner[0][0], corner[0][1]) for corner in corners]
add = np.sum(corners)
top_l = corners[np.argmin(add)]
bottom_r = corners[np.argmax(add)]
diff = np.diff(corners, 1)
top_r = corners[np.argmin(diff)]
bottom_l = corners[np.argmax(diff)]
return (top_r, top_l, bottom_l, bottom_r)
ordered_corners = orderCornerPoints(corners)
top_r, top_l, bottom_l, bottom_r = ordered_corners
#Find width of new image (Using distance formula)
width_A = np.sqrt(((bottom_r[0] - bottom_l[0]) ** 2) + ((bottom_r[1] - bottom_l[1]) ** 2))
width_B = np.sqrt(((top_r[0] - top_l[0]) ** 2) + ((top_r[1] - top_l[1]) ** 2))
width = max(int(width_A), int(width_B))
#Find height of new image (Using distance formula)
height_A = np.sqrt(((top_r[0] - bottom_r[0]) ** 2) + ((top_r[1] - bottom_r[1]) ** 2))
height_B = np.sqrt(((top_l[0] - bottom_l[0]) ** 2) + ((top_l[1] - bottom_l[1]) ** 2))
height = max(int(height_A), int(height_B))
#Make top down view
#Order: top-right, top-left, bottom-left, bottom-right
dimensions = np.array([[width, 0], [0, 0], [0, height], [width, height]], dtype = "float32")
#Make ordered_corners var numpy format
ordered_corners = np.array(ordered_corners, dtype = 'float32')
#Transform the perspective
m = cv.getPerspectiveTransform(ordered_corners, dimensions)
return cv.warpPerspective(img, m, (width, height))
#Processes image (Grayscale, median blur, adaptive threshold)
def processImage(img):
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
blur = cv.medianBlur(gray, 3)
thresh = cv.adaptiveThreshold(blur,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY_INV,11,3)
return thresh
#Find and sort contours
img_processed = processImage(img)
cnts = cv.findContours(img_processed, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
cnts = sorted(cnts, key=cv.contourArea, reverse=True)
#Perform perspective transform
peri = cv.arcLength(cnts[0], True)
approx = cv.approxPolyDP(cnts[0], 0.01 * peri, True)
transformed = perspectiveTransform(img, approx)
#Draw lines
height = transformed.shape[0]
width = transformed.shape[1]
#for vertical lines
line_x = 0
x_increment_val = round((1/9) * width)
#for horizontal lines
line_y = 0
y_increment_val = round((1/9) * height)
#vertical lines
for i in range(10):
cv.line(transformed, (line_x, 0), (line_x, height), (0, 0, 255), 1)
line_x += x_increment_val
#horizontal lines
for i in range(10):
cv.line(transformed, (0, line_y), (width, line_y), (0, 0, 255), 1)
line_y += y_increment_val
#Show image
cv.imshow('Sudoku', transformed)
cv.waitKey(0)
cv.destroyAllWindows()
这是我的输入图像
看来是输入的角计算错误了。在您的 perspectiveTransform
函数中,您有以下代码段,显然计算了数独游戏的四个角:
# Corners to points
corners = [(corner[0][0], corner[0][1]) for corner in corners]
add = np.sum(corners)
top_l = corners[np.argmin(add)]
bottom_r = corners[np.argmax(add)]
diff = np.diff(corners, 1)
top_r = corners[np.argmin(diff)]
bottom_l = corners[np.argmax(diff)]
return (top_r, top_l, bottom_l, bottom_r)
检查 (top_r, top_l, bottom_l, bottom_r)
元组。那些坐标是错误的,我不知道你在计算corners
之后做了什么,但是top_l
、bottom_r
、top_r
和bottom_l
计算肯定有问题。如果你像这样硬编码元组:
ordered_corners = [(697, 99), (108, 121), (52, 730), (735, 730)] # orderCornerPoints(corners)
要通过拼图的实际角点(从右上角开始,逆时针方向),那么你的变换是正确的:
建议:当程序出现bug时,使用调试器逐步调试,检查变量的实际值和中间计算。
我正在从事一个项目,该项目由我的代码组成,用于识别数独谜题的图像,然后解决它。我现在正在研究图像识别部分。它工作正常,直到我意识到我一直在使整个程序在 y 轴上翻转。所以我更换了
dimensions = np.array([[0, 0], [width, 0], [width, height], [0, height]], dtype = "float32")
和
dimensions = np.array([[width, 0], [0, 0], [0, height], [width, height]], dtype = "float32")
这似乎改变了一切,现在我 运行 我只得到一张灰色图像。 这是我的代码。 请注意,我是 opencv 的新手。另外,我在我的代码中画线,当我 运行 它时,这些线仍然出现。只是实际图像没有出现。
#Imports
import cv2 as cv
import numpy as np
import math
#Load image
img = cv.imread('sudoku_test_image.jpeg')
#Transforms perspective
def perspectiveTransform(img, corners):
def orderCornerPoints(corners):
#Corners sperated into their own points
#Index 0 = top-right
# 1 = top-left
# 2 = bottom-left
# 3 = bottom-right
#Corners to points
corners = [(corner[0][0], corner[0][1]) for corner in corners]
add = np.sum(corners)
top_l = corners[np.argmin(add)]
bottom_r = corners[np.argmax(add)]
diff = np.diff(corners, 1)
top_r = corners[np.argmin(diff)]
bottom_l = corners[np.argmax(diff)]
return (top_r, top_l, bottom_l, bottom_r)
ordered_corners = orderCornerPoints(corners)
top_r, top_l, bottom_l, bottom_r = ordered_corners
#Find width of new image (Using distance formula)
width_A = np.sqrt(((bottom_r[0] - bottom_l[0]) ** 2) + ((bottom_r[1] - bottom_l[1]) ** 2))
width_B = np.sqrt(((top_r[0] - top_l[0]) ** 2) + ((top_r[1] - top_l[1]) ** 2))
width = max(int(width_A), int(width_B))
#Find height of new image (Using distance formula)
height_A = np.sqrt(((top_r[0] - bottom_r[0]) ** 2) + ((top_r[1] - bottom_r[1]) ** 2))
height_B = np.sqrt(((top_l[0] - bottom_l[0]) ** 2) + ((top_l[1] - bottom_l[1]) ** 2))
height = max(int(height_A), int(height_B))
#Make top down view
#Order: top-right, top-left, bottom-left, bottom-right
dimensions = np.array([[width, 0], [0, 0], [0, height], [width, height]], dtype = "float32")
#Make ordered_corners var numpy format
ordered_corners = np.array(ordered_corners, dtype = 'float32')
#Transform the perspective
m = cv.getPerspectiveTransform(ordered_corners, dimensions)
return cv.warpPerspective(img, m, (width, height))
#Processes image (Grayscale, median blur, adaptive threshold)
def processImage(img):
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
blur = cv.medianBlur(gray, 3)
thresh = cv.adaptiveThreshold(blur,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY_INV,11,3)
return thresh
#Find and sort contours
img_processed = processImage(img)
cnts = cv.findContours(img_processed, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
cnts = sorted(cnts, key=cv.contourArea, reverse=True)
#Perform perspective transform
peri = cv.arcLength(cnts[0], True)
approx = cv.approxPolyDP(cnts[0], 0.01 * peri, True)
transformed = perspectiveTransform(img, approx)
#Draw lines
height = transformed.shape[0]
width = transformed.shape[1]
#for vertical lines
line_x = 0
x_increment_val = round((1/9) * width)
#for horizontal lines
line_y = 0
y_increment_val = round((1/9) * height)
#vertical lines
for i in range(10):
cv.line(transformed, (line_x, 0), (line_x, height), (0, 0, 255), 1)
line_x += x_increment_val
#horizontal lines
for i in range(10):
cv.line(transformed, (0, line_y), (width, line_y), (0, 0, 255), 1)
line_y += y_increment_val
#Show image
cv.imshow('Sudoku', transformed)
cv.waitKey(0)
cv.destroyAllWindows()
这是我的输入图像
看来是输入的角计算错误了。在您的 perspectiveTransform
函数中,您有以下代码段,显然计算了数独游戏的四个角:
# Corners to points
corners = [(corner[0][0], corner[0][1]) for corner in corners]
add = np.sum(corners)
top_l = corners[np.argmin(add)]
bottom_r = corners[np.argmax(add)]
diff = np.diff(corners, 1)
top_r = corners[np.argmin(diff)]
bottom_l = corners[np.argmax(diff)]
return (top_r, top_l, bottom_l, bottom_r)
检查 (top_r, top_l, bottom_l, bottom_r)
元组。那些坐标是错误的,我不知道你在计算corners
之后做了什么,但是top_l
、bottom_r
、top_r
和bottom_l
计算肯定有问题。如果你像这样硬编码元组:
ordered_corners = [(697, 99), (108, 121), (52, 730), (735, 730)] # orderCornerPoints(corners)
要通过拼图的实际角点(从右上角开始,逆时针方向),那么你的变换是正确的:
建议:当程序出现bug时,使用调试器逐步调试,检查变量的实际值和中间计算。