Python OpenCV ошибки рисования после манипулирования массивом с NumPy
Я читаю изображение с OpenCV и пытаюсь что-то с ним сделать в numpy (повернуть на 90 градусов). Просмотр результата с imshow
из matplotlib все работает нормально - изображение поворачивается. Однако я не могу использовать методы рисования из OpenCV на новом изображении. В следующем коде (я запускаю это в облачной таблице Sagemath):
%python
import cv2
import matplotlib.pyplot as plt
import numpy as np
import os, sys
image = np.array( cv2.imread('imagename.png') )
plt.imshow(image,cmap='gray')
image = np.array(np.rot90(image,3) ) # put it right side up
plt.imshow(image,cmap='gray')
cv2.rectangle(image,(0,0),(100,100),(255,0,0),2)
plt.imshow(image,cmap='gray')
Я получаю следующую ошибку на cv2.rectangle()
команда:
TypeError: Layout of the output array img is incompatible with cv::Mat (step[ndims-1] != elemsize or step[1] != elemsize*nchannels)
Ошибка исчезнет, если я использую np.array(np.rot90(image,4) )
вместо этого (т.е. поверните его на 360). Таким образом, кажется, что изменение размеров портит это. Хранит ли OpenCV размеры где-то внутри, что мне нужно обновить или что-то в этом роде?
РЕДАКТИРОВАТЬ: Добавление image = image.copy()
после rot90()
решил проблему. Смотрите ответ Rayryeng ниже.
3 ответа
По-видимому, это ошибка в оболочке Python OpenCV. Если вы посмотрите на этот вопрос здесь: np.rot90 () повреждает изображение opencv, очевидно, что вращение, которое не приводит к возврату к исходным размерам, повреждает изображение, и OP в этом посте испытывает ту же ошибку, что и вы. FWIW, я также испытал ту же ошибку.... понятия не имею, почему.
Обойти это можно, сделав копию изображения после поворота, а затем показать изображение. Это я не могу объяснить, но это похоже на работу. Также обязательно позвоните plt.show()
в конце вашего кода, чтобы показать изображение:
import cv2
import matplotlib.pyplot as plt
import numpy as np
import os, sys
image = np.array( cv2.imread('imagename.png') )
plt.imshow(image,cmap='gray')
image = np.array(np.rot90(image,3) ) # put it right side up
image = image.copy() # Change
plt.imshow(image,cmap='gray')
cv2.rectangle(image,(0,0),(100,100),(255,0,0),2)
plt.imshow(image,cmap='gray')
plt.show() # Show image
Я столкнулся с той же проблемой с numpy 1.11.2 и opencv 3.3.0. Не знаю почему, но это сделало всю работу за меня. Перед использованием cv2.rectangle добавьте строку ниже:
image1 = image1.transpose((1,0)).astype(np.uint8).copy()
Конвертировать тип данных работает для моей проблемы. Перед преобразованием изображение имеет тип np.int64.
image = image.astype(np.int32) # convert data type