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
Другие вопросы по тегам