#python #opencv
#python #opencv
Вопрос:
Я написал код на python opencv. Я пытаюсь записать обработанное изображение обратно на диск, но изображение не сохраняется, и оно не показывает никаких ошибок (время выполнения и компиляция) Код является
"""
Created on Wed Oct 19 18:07:34 2016
@author: Niladri
"""
import numpy as np
import cv2
if __name__ == '__main__':
import sys
img = cv2.imread('C:UsersNiladriDesktopTexturesCom_LandscapeTropical0080_2_S.jpg')
if img is None:
print 'Failed to load image file:'
sys.exit(1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
h, w = img.shape[:2]
eigen = cv2.cornerEigenValsAndVecs(gray, 15, 3)
eigen = eigen.reshape(h, w, 3, 2) # [[e1, e2], v1, v2]
#flow = eigen[:,:,2]
iter_n = 10
sigma = 5
str_sigma = 3*sigma
blend = 0.5
img2 = img
for i in xrange(iter_n):
print i,
gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
eigen = cv2.cornerEigenValsAndVecs(gray, str_sigma, 3)
eigen = eigen.reshape(h, w, 3, 2) # [[e1, e2], v1, v2]
x, y = eigen[:,:,1,0], eigen[:,:,1,1]
print eigen
gxx = cv2.Sobel(gray, cv2.CV_32F, 2, 0, ksize=sigma)
gxy = cv2.Sobel(gray, cv2.CV_32F, 1, 1, ksize=sigma)
gyy = cv2.Sobel(gray, cv2.CV_32F, 0, 2, ksize=sigma)
gvv = x*x*gxx 2*x*y*gxy y*y*gyy
m = gvv < 0
ero = cv2.erode(img, None)
dil = cv2.dilate(img, None)
img1 = ero
img1[m] = dil[m]
img2 = np.uint8(img2*(1.0 - blend) img1*blend)
#print 'done'
cv2.imshow('dst_rt', img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
#cv2.imwrite('C:UsersNiladriDesktopleaf_image_shock_filtered.jpg', img2)
for i in xrange(iter_n):
print i,
gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
eigen = cv2.cornerEigenValsAndVecs(gray, str_sigma, 3)
eigen = eigen.reshape(h, w, 3, 2) # [[e1, e2], v1, v2]
x, y = eigen[:,:,1,0], eigen[:,:,1,1]
print eigen
gxx = cv2.Sobel(gray, cv2.CV_32F, 2, 0, ksize=sigma)
gxy = cv2.Sobel(gray, cv2.CV_32F, 1, 1, ksize=sigma)
gyy = cv2.Sobel(gray, cv2.CV_32F, 0, 2, ksize=sigma)
gvv = x*x*gxx 2*x*y*gxy y*y*gyy
m = gvv < 0
ero = cv2.erode(img, None)
dil = cv2.dilate(img, None)
img1 = dil
img1[m] = ero[m]
img2 = np.uint8(img2*(1.0 - blend) img1*blend)
print 'done'
#cv2.imwrite('D:IPtropical_image_sig5.bmp', img2)
cv2.imshow('dst_rt', img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
#cv2.imshow('dst_rt', img2)
cv2.imwrite('C:UsersNiladriDesktoptropical_image_sig5.bmp', img2)
Может кто-нибудь, пожалуйста, сказать мне, почему это не работает. cv2.imshow работает должным образом (поскольку он показывает правильное изображение).
Спасибо и с уважением
Ниладри
Ответ №1:
Как общее и абсолютное правило, вы должны защищать строки пути к Windows (содержащие обратную косую черту) с r
префиксом, иначе некоторые символы интерпретируются (например: n,b,v,x
aaaaand t
, полный список здесь):
поэтому при выполнении этого:
cv2.imwrite('C:UsersNiladriDesktoptropical_image_sig5.bmp', img2)
вы пытаетесь сохранить в C:UsersNiladriDesktop<TAB>ropical_image_sig5.bmp
И самое неприятное в imread
и imwrite
заключается в том, что эти функции не генерируют исключения при ошибках, а молча завершают работу. imwrite
ВОЗВРАТ False
>>> cv2.imread("D:/nonexisting.jpg") # this returns None, no error
>>> s = cv2.imread("D:/sloth_book.jpg") # this works
>>> s
array([[[250, 250, 250],
[246, 246, 246],
[255, 255, 255],
...,
>>> cv2.imwrite("inexistent_dir/file.jpg",s) # dir doesn't exist, write fails
False
Поэтому вам нужно проверить возвращаемое значение этих функций.
Сделайте это:
if not cv2.imwrite(r'C:UsersNiladriDesktoptropical_image_sig5.bmp', img2):
raise Exception("Could not write image")
Примечание: чтение работает нормально, потому что «экранированные» заглавные буквы не имеют особого значения в python 2 ( U
и N
имеют значение в python 3, так что это не сработало бы)
И если возникает ошибка, программа теперь громко жалуется.
Комментарии:
1. Из-за отсутствия каталогов запись завершается без сбоев. Необходимо создать требуемые каталоги перед попыткой записи. [Это была проблема, с которой я столкнулся. Размещаю его там для всех, кому это нужно.]
2. Хорошо, если бы вы могли определить ошибку на глаз. Что делать, если путь правильный, но cv2.imwrite() возвращает False? Есть ли какой-либо способ получить сообщение об ошибке?
3. Вероятно, это помогло бы сначала проверить наличие разрешений в каталоге. Поскольку он не возвращает никаких исключений, трудно понять, почему произошел сбой (прямые вызовы API библиотеки c глубоко внизу)
Ответ №2:
Как предположил Жан, ошибка связана с тем, что интерпретируется как escape-последовательность. Следовательно, его всегда безопаснее использовать os.path.join()
, поскольку он более кроссплатформенный, и вам не нужно беспокоиться о проблеме с escape-последовательностью. Например, в вашем случае вам больше не нужно беспокоиться о первых нескольких аргументах, поскольку это ваш домашний каталог
import os
cv2.imwrite(os.path.join(os.path.expanduser('~'),'Desktop','tropical_image_sig5.bmp'), img2)
os.path.expanduser('~')
напрямую вернет ваш домашний каталог.
Комментарии:
1. вероятно, наиболее переносимое решение