#python #opencv #computer-vision #signal-processing
#python #opencv #компьютерное зрение #обработка сигналов
Вопрос:
Я пытаюсь использовать функцию dct () в OpenCV для вычисления дискретного косинусного преобразования, но получаю странные результаты.
Мой скрипт:
import os, sys
import cv, cv2
import numpy as np
fn1 = 'original.jpg'
img1 = cv2.imread(fn1, cv2.CV_LOAD_IMAGE_GRAYSCALE)
h, w = img1.shape[:2]
vis0 = np.zeros((h,w), np.float32)
vis0[:h, :w] = img1
vis1 = cv2.dct(vis0)
img2 = cv.CreateMat(vis1.shape[0], vis1.shape[1], cv.CV_32FC3)
cv.CvtColor(cv.fromarray(vis1), img2, cv.CV_GRAY2BGR)
cv.ShowImage('',img2)
cv2.waitKey()
cv.SaveImage('saved.jpg', img2)
Кажется, что это выполняется без ошибок, но изображение, показанное ShowImage (), и изображение, сохраненное SaveImage (), выглядят очень разными. К сожалению, я не могу найти никаких образцов изображений, обработанных DCT, поэтому я не уверен, какое из них, если вообще какое-либо, правильное.
Исходное изображение:
Показанное изображение DCT:
Сохраненный образ DCT:
Почему существует такая разница между показанным и сохраненным изображениями DCT? Что правильно?
Комментарии:
1. Просто предположение, но сохраненный DCT, на мой взгляд, правильный, а показанный DCT выглядит так, как будто он каким-то образом потерял большую часть информации (как будто все пиксели> эпсилон по какой-то причине были сопоставлены с 1). Возможно, сохраненное изображение находится в диапазоне 0-255, и показанное изображение ошибочно обрезало его до 0-1.
Ответ №1:
Кажется, вы отобразили сложный вывод DCT. И, поскольку вы пытались сохранить 2-канальное изображение (DCT выводит 2 канала — один для реальной, один для мнимой части), он сохранил только реальную часть (которая каким-то образом близка к величине).
Итак, из вашего вывода DCT используйте функции magnitude () и phase () для извлечения полезной информации. Отображать их отдельно,
И, самое главное, внимательно прочитайте о DCT ( http://en.wikipedia.org/wiki/Discrete_cosine_transform ) итак, вы знаете, что делаете.
Комментарии:
1. Откуда вы получаете информацию о выходе DCT ()? То, что написано в Википедии, и то, что реализовано на самом деле, обычно очень разные вещи. Все документы OpenCV, которые я нашел, и даже мой опубликованный код показывают, что он возвращает ту же форму, что и входной массив, который для изображения в оттенках серого будет одним каналом, а не двумя. opencv.willowgarage.com/documentation/cpp /…
2. Найдите opencv refman, который поставляется с дистрибутивом. Это называется opencv.pdf или opencv_refman.pdf, в зависимости от используемой вами версии. Это более подробно, чем онлайн-ссылка. И та же форма не равна тому же номеру канала. попробуйте cout << matDct.channels(); чтобы разрешить загадку 🙂
3. Но я использовал его, и он дает мне двухканальные данные с плавающей запятой одинарной точности. Как указано в refman
4. @vasile… Я не знаю, что вам сказать. Код не лжет, и cv2.dct() выводит numpy ndarray … который не имеет функции channels(). Обратите внимание, я использую оболочку Python 2.3 (как cv, так и cv2), а не C API. Возможно, недавняя оболочка Python работает иначе, чем то, к чему вы привыкли в прошлом?
5. Я не использую python, но я использовал больше версий ocv, включая 2.3 и 2.3.1. и опубликованные вами изображения ясно показывают, что существуют сложная (первая) и реальная (вторая) части DCT. вызовите magnitude() для вывода DCT и проверьте результат. Я должен быть близок ко второму изображению (но не идентичен).
Ответ №2:
сохраненное изображение фактически такое же, но значения привязаны к [0 ..255] и преобразованы в байт (numpy.uint8) перед сохранением в формате JPEG. отрицательные значения устанавливаются равными нулю, а значения выше 255 устанавливаются равными 255.
cv2.imshow("before_save", vis1)
vis1[vis1>255] = 255
vis1[vis1<0] = 0
cv2.imshow("saved", vis1.astype(np.uint8))