【问题标题】:Calculate Discrete Cosine Transformation of Image with OpenCV用 OpenCV 计算图像的离散余弦变换
【发布时间】:2011-10-28 15:27:16
【问题描述】:

我正在尝试使用 OpenCV 2.3 Python 包装器来计算图像的 DCT。据说,图像 == numpy 数组 == CV 矩阵,所以我认为这应该可行:

import cv2
img1 = cv2.imread('myimage.jpg', cv2.CV_LOAD_IMAGE_GRAYSCALE)
img2 = cv2.dct(img1)

但是,这会引发错误:

cv2.error: /usr/local/lib/OpenCV-2.3.1/modules/core/src/dxt.cpp:2247: error: (-215) type == CV_32FC1 || type == CV_64FC1 in function dct

我意识到错误意味着输入应该是 32 位或 64 位单通道浮点矩阵。但是,我认为这就是我的图像在指定灰度时应该加载的方式,或者至少它应该足够接近,以便 CV2 应该能够计算出转换。

使用 cv2 将图像转换为 DCT 的适当方法是什么?

【问题讨论】:

    标签: python opencv computer-vision


    【解决方案1】:

    似乎没有任何简单的方法可以用 cv2 做到这一点。我能找到的最接近的解决方案是:

    import cv, cv2
    import numpy as np
    
    img1 = cv2.imread('myimage.jpg', 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.SaveImage('output.jpg', img2)
    

    【讨论】:

      【解决方案2】:

      这是我从 openCV 论坛获得的解决方案,它有效。

      img = cv2.imread(fn, 0)      # 1 chan, grayscale!
      imf = np.float32(img)/255.0  # float conversion/scale
      dst = cv2.dct(imf)           # the dct
      img = np.uint8(dst)*255.0    # convert back
      

      【讨论】:

      【解决方案3】:

      嗯,当您将图像加载为灰度时,它实际上是以每像素 8 位读取的,而不是 32 位浮点值。

      你会怎么做:

      img1_32f = cv.CreateImage( cv.GetSize(img1), cv.IPL_DEPTH_64F, 1)
      cv.Scale(img1, img1_32f, 1.0, 0.0)
      

      另外,请查看dft.py 示例。这也应该让您了解如何使用dft

      【讨论】:

      • 谢谢。但是,我知道如何使用 cv 来做到这一点。我的问题是如何使用 cv2 来做到这一点。还是 OpenCV 团队计划无限期地维护 cv 和 cv2 模块?
      • 另外,您的示例不适用于 cv2.imread() 的输出。
      【解决方案4】:

      Numpy 具有切片运算符,用于在不同顺序的数组之间工作。

      import cv2
      import cv2.cv as cv
      import numpy as np   
      
      img1 = cv2.imread('myimage.jpg')
      # or use cv2.CV_LOAD_IMAGE_GRAYSCALE 
      img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
      cv2.imshow('input', img1)
      w,h = img1.shape
      # make a 32bit float for doing the dct within
      img2 = np.zeros((w,h), dtype=np.float32)
      print img1.shape, img2.shape
      img2 = img2+img1[:w, :h]
      dct1 = cv2.dct(img2)
      key = -1
      while(key < 0):
          cv2.imshow("DCT", dct1)
          key = cv2.waitKey(1)
      cv2.destroyAllWindows()
      

      【讨论】:

        【解决方案5】:

        我不想写这个答案,但是当我看到一些答案是错误的时候被投票赞成,我决定写。

        dct 操作适用于任何范围的输入,所以我真的不明白为什么其他人将其缩放到 [0, 1]。但是在opencv中,你需要传递numpy.float32数字。

        x = np.array([8, 16, 24 , 32, 40, 48, 56, 64])
        cv2.dct(np.float32(x))
        
        # output
        array([[ 101.82337189],
               [ -51.53858566],
               [   0.        ],
               [  -5.38763857],
               [   0.        ],
               [  -1.60722351],
               [   0.        ],
               [  -0.40561762]], dtype=float32)
        

        但是如果你缩放它,几乎所有的小值都会丢失。

        以下是公式和示例的链接: https://users.cs.cf.ac.uk/Dave.Marshall/Multimedia/node231.html#DCTbasis

        【讨论】:

          【解决方案6】:

          以下是如何使用 scipy 进行操作:

          import os.path
          import numpy as np
          from PIL import Image
          from scipy.fftpack import fft, dct
          
          if __name__ == '__main__':
              image_counter = 1
          
              # Apply DCT to the noisy image patches.
              noise_image_path = 'noise_images/' + str(image_counter) + '.png'
              noise_image = Image.open(noise_image_path)         
              noise_dct_data = dct(noise_image)
              print(noise_dct_data)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-05-30
            • 1970-01-01
            相关资源
            最近更新 更多