使用OpenCV和c++将图像帧分割成8*8进行DCT

Split image frame into 8*8 for DCT using OpenCV and C++

本文关键字:进行 DCT 分割 OpenCV c++ 图像 使用      更新时间:2023-10-16

我需要将fullPath传递给方法FrameTo8by8()。在FrameTo8by8()中,它将把每一帧分割成8*8块。(例:我的视频分辨率是1280*720 = 921600。之后921600/64(8*8)= 14400。所以总共有14400个8*8的方块

VideoSplitEngine.h

class VideoSplitEngine
{
    public:
    static VideoCapture capture;
    static Mat fullimage;
    //Default constructor
    VideoSplitEngine();
    //Declare a virtual destructor:
    virtual ~VideoSplitEngine();
    //Method
    Mat Start();    
    void FrameTo8by8() const; 
    string GetFilePath() const;
    private:
};

VideoSplitEngine.cpp

#include "StdAfx.h"
#include "VideoSplitEngine.h"
#include "UserInfo.h"
#include "Common.h"
VideoCapture VideoSplitEngine::capture;
Mat VideoSplitEngine::fullimage;
Mat VideoSplitEngine::Start()
string VideoSplitEngine::GetFilePath() const
{
  cout<< endl;
  cout << "Place video in Desktop and enter file name (e.g. vid.avi):" << endl;
  cout<<"----------------------------------------------------------"<< endl;
  //Get user desktop file path
  string fullPath;
  string userProfile = getenv("userprofile");   //GetEnvironmentVariable() is to get current userprofile (e.g."C:UsersL30807")
  string path = userProfile + "\Desktop\";
  string vid;
  getline (cin, vid);       //Prompt to input file name
  fullPath = path + vid;
  capture.open(fullPath); //Read video
  cout<< endl;
  return fullPath;
}
Mat VideoSplitEngine::Start()
{
  while(1)
  {
    bool bSuccess = capture.read(fullimage); // read a new frame from video
    if (!bSuccess) //if not success, break loop
    {
        cout << "End of video" << endl;
        destroyWindow("Original Video");
        break;
    }
    imshow("Original Video", fullimage); //show the frame in "Original Video" window
    if(waitKey(30) == 27) //wait for 'esc' key press for 30 ms. If 'esc' key is pressed, break loop
    {
        cout << "esc key is pressed by user" << endl; 
        break; 
    }
  }
return fullimage;
}
void VideoSplitEngine::FrameTo8by8() const
{
    namedWindow("Original", CV_WINDOW_AUTOSIZE); 
    imshow("Original", fullimage); 
    int width = fullimage.size().width; 
    int height = fullimage.size().width; 
    cout << "Original image Width x Height is " << width << "x" << height << endl; 
    // Leave original alone, work on a copy 
    Mat dctImage = fullimage.clone();
    // Step through the copied image with rectangles size 8x8 
    // For each block, split into planes, do dct, and merge back 
    // into the block. (This will affect the image from 
    // which the block is selected each time.) 
    for (int i = 0; i < height; i += 8) 
    { 
        for (int j = 0; j < width; j+= 8) 
        {
            Mat block = dctImage(Rect(i, j, 8, 8));
            vector<Mat> planes; 
            split(block, planes);
            vector<Mat> outplanes(planes.size());
            for (size_t k = 0; k < planes.size(); k++)
            {
                planes[k].convertTo(planes[k], CV_32FC1); 
                dct(planes[k], outplanes[k]);
                outplanes[k].convertTo(outplanes[k], CV_8UC1);
            }
                merge(outplanes, block); 
        } 
    } 
    namedWindow("dctBlockImage"); 
    imshow("dctBlockImage", dctImage);
    waitKey(30); 
}

我需要帮助如何分割它或有其他方法来做到这一点?

1。@berak是对的。函数Rect()的原型是Rect(x,y,width,height)。表示宽度的j应该是x。(实际上我还没有从http://docs.opencv.org/2.4/index.html找到Rect()的原型,但cvRect()在C API是cvRect(x,y,宽度,高度)。我想他们的原型可能是一样的。

2。for (int i = 0; i < height; i += 8)for (int j = 0; j < width; j+= 8)会导致错误"Unhandled exception at…"。将它们改为for (int i = 0; i < (height/8)*8; i += 8)for (int j = 0; j < (width/8)*8; j+= 8),就可以解决这个错误。

3。@user3743939如果你解决了你的问题,请贴出你的解决方案来帮助别人。