C++ Realize discrete cosine transform （ The parameter is a two-dimensional pointer ）

Write it at the front

So far, I have read quite a few papers on mesh watermarking and so on , But the progress of the paper has not been improved , This month, I'm going to select some classic papers , The algorithm is implemented . In the process of realizing the thesis , It is found that there are some algorithms in this paper . So I thought of realizing DCT . Although the code of this article is very similar to many existing codes on the Internet , There's not much difference in thinking , But there is an important improvement in this paper . specifically , Available online DCT The input of the algorithm is a fixed two-dimensional array . When a two-dimensional array is passed as a function parameter , At least you need to give the size of the second dimension , Otherwise, the compiler will report an error . But in graphics and image processing , When we want to use DCT The transformation of a figure or image into a frequency domain , Maybe I'm calling DCT Function does not know the size of the graph or image in advance , Therefore, this way of parameter transfer greatly limits the use of code . An improvement of this paper is ,DCT The argument to the function is no longer a two-dimensional array , Instead, I pass in a two-dimensional pointer , Function function is realized by manual addressing .

Theoretical basis of discrete cosine transform

I think you are familiar with Fourier transform . In fact, DCT is similar to Fourier transform . The definition of 2D DCT is expressed by the following formula ： The inverse transformation is expressed as follows ： Code implementation

According to the formula above , It's easy to write code

// DCT - Discrete Cosine Transform
void DCT( double ** input, double ** output, int row, int col )
{
cout<<"Test in DCT"<<endl;
double ALPHA, BETA;
int u = 0;
int v = 0;
int i = 0;
int j = 0; for(u = 0; u < row; u++)
{
for(v = 0; v < col; v++)
{
if(u == 0)
{
ALPHA = sqrt(1.0 / row);
}
else
{
ALPHA = sqrt(2.0 / row);
} if(v == 0)
{
BETA = sqrt(1.0 / col);
}
else
{
BETA = sqrt(2.0 / col);
} double tmp = 0.0;
for(i = 0; i < row; i++)
{
for(j = 0; j < col; j++)
{
tmp += *((double*) input + col*i + j ) * cos((2*i+1)*u*PI/(2.0 * row)) * cos((2*j+1)*v*PI/(2.0 * col));
}
}
*((double*) output + col*u + v) = ALPHA * BETA * tmp;
}
} cout << "The result of DCT:" << endl;
for(int m = 0; m < row; m++)
{
for(int n= 0; n < col; n++)
{
cout <<setw(8)<< *((double*) output + col*m + n)<<" \t";
}
cout << endl;
}
}

Note that the function parameters in the code are not two-dimensional arrays , It's a pointer to a two-dimensional array . The code for the corresponding inverse transformation is as follows ：

// Inverse DCT
void IDCT( double ** input, double ** output, int row, int col )
{
cout<<"Test in IDCT"<<endl;
double ALPHA, BETA;
int u = 0;
int v = 0;
int i = 0;
int j = 0; for(i = 0; i < row; i++)
{
for( j = 0; j < col; j++)
{
double tmp = 0.0;
for(u = 0; u < row; u++)
{
for(v = 0; v < col; v++)
{
if(u == 0)
{
ALPHA = sqrt(1.0 / row);
}
else
{
ALPHA = sqrt(2.0 / row);
}
if(v == 0)
{
BETA = sqrt(1.0 / col);
}
else
{
BETA = sqrt(2.0 / col);
}
tmp += ALPHA * BETA * *((double*) input + col*u + v )* cos((2*i+1)*u*PI/(2.0 * row)) * cos((2*j+1)*v*PI/(2.0 * col));
}
}
*((double*) output + col*i + j) = tmp;
}
} cout << "The result of IDCT:" << endl;
for(int m = 0; m < row; m++)
{
for(int n= 0; n < col; n++)
{
cout <<setw(8)<< *((double*) output + col*m + n)<<"\t";
}
cout << endl;
}
}

Test code

#include <iostream>
#include <math.h>
#include<cstdio>
#include <iomanip>
#include<algorithm> using namespace std;
#define PI 3.1415926
int main()
{
int i = 0;
int j = 0;
int u = 0;
int v = 0; const int rows = 3;
const int cols = 3; double inputdata[rows][cols] = {
{89,101,114},
{97,115,131},
{114,134,159},
}; double outputdata[rows][cols]; DCT( (double**)inputdata, (double**)outputdata,rows, cols );
IDCT( (double**)outputdata, (double**)inputdata,rows,cols ); system("pause");
return 0;
}

The program runs as follows ： Summary

Then you can upgrade the code , Instead of passing two-dimensional arrays as parameters , But use Eigen Type as parameter , This makes the code clearer , And memory management is more convenient .

Reprint please indicate the source ：http://www.cnblogs.com/scut-linmaojiang/p/5013590.html

C++ Realize discrete cosine transform （ The parameter is a two-dimensional pointer ） More articles about

1. C# WeChat official account interface development example - Advanced interface - Apply for QR code with parameters

Recently, the company involves wechat binding users , Made advanced interface - Apply for QR code with parameters , Summarize the development interface of wechat . Wechat interface development is used in addition to message xml The reply is basically in json To convey information in the form of (post/get), The methods of development are basically one ...

2. Force.com Wechat Development Series （ 8、 ... and ） Generate QR code with parameters

In order to meet the needs of user channel promotion analysis , The public platform provides an interface for generating two-dimensional code . Using this interface, multiple QR codes with different scene values can be obtained , After user scanning , The official account can receive event push. . There are currently two types of QR codes , Temporary QR code and permanent QR code ...

3. Wechat development ——Php Batch generation of QR code with parameters

QR code with parameters is very useful for channel marketing promotion , Multiple QR codes with different scene values can be obtained , After user scanning , The official account can receive event push. , Fortunately, wechat has opened this interface , Let's study it . Please refer to , Wechat public service ...

4. C Analysis of the pointer in language ——type *name[] In function arguments , It's a two-dimensional pointer

type *name[] Declaring in a function parameter is not the same as not declaring in a function . type *name[] If you declare in a function parameter , be name It's a two-dimensional pointer , It's not an array of pointers , And if you don't declare it in a function parameter , be ...

5. WeChat official account generates two-dimensional code with parameters asp Source download

I have nothing to do at night , Contact a friend , Let's help write a WeChat official account. asp Generate QR code with parameters , If someone else has swept the map, if he has paid attention to the official account number. , Directly into the official account. , If you don't pay attention, you will be prompted to pay attention , After paying attention, the wechat user information will be automatically obtained and saved ...

6. Two ways to initialize a linked list through an array ： Reference to pointer node *&amp;tail And a pointer to a pointer （ Two dimensional pointer ）node **tail

Interview questions : Reverse operation of single linked list / Linked list reverse order related articles Click on the open void init_node(node *tail,char *init_array) It's not right to declare a function like this , The original idea of the function is to initialize the linked list through an array ...

7. 【 Video development 】OpenCV in Mat, Image two-dimensional pointer and CxImage Transformation of a class

In image processing , Common function interfaces are OpenCV Medium Mat Image class , Sometimes it is necessary to use two-dimensional pointer to open up memory and store image data directly , Sometimes you need to use CxImage Class to store images . This paper mainly summarizes the transformation of image data between these three storage methods ...

8. Two dimensional pointer *(void **) The study of （uC/OS-II Case study ） 《 Reprint 》

uC/OS-II The most difficult part of memory management functions is the two-dimensional pointer , In this paper, the two-dimensional pointer is analyzed and explained in detail with pictures and text . Look at the end of this article , Believe in C There will be further understanding of the concept of pointer . One .OSMemCreate( ) Letter ...

9. Of the longest common subsequence C++ Realization --- The usage of two-dimensional pointer is attached

I've been thinking for a long time about what to write in the first blog here , Just these two days, I saw the dynamic programming again LCS I think it's a bit interesting , So I wrote it , Let's post the first blog . #include<iostream> #includ ...

Random recommendation

1. About installation Apache after , analysis PHP Configuration of

You need to configure four places LoadModule php5_module modules/libphp5.soServerName localhost:80DirectoryIndex index.phpAdd ...

2. Tomcat in JVM Memory overflow and reasonable configuration and maxThreads How to configure ( turn )

source :http://www.tot.name/html/20150530/20150530102930.htm Tomcat It can't run directly on the computer itself , Need to rely on hardware based operating system and a Java virtual ...

3. sublime text2 Open the file containing Chinese and it will be appended automatically .dump The solution

use sublime text2 open .c, .h,.txt Wait for the file to be appended automatically .dump suffix , It's opening .c,.h I can't recognize it when I wait for the file , So we can't do syntax coloring properly , The Internet says it's because it's installed GBK Encodin ...

4. NSString、NSArray、NSDictionary and NSData Data storage

#import "ViewController.h" @interface ViewController () @end @implementation ViewControlle ...

5. oracle Cursor in

oracle Cursor in Easy to understand sql Code directly ! -- Simple cursor use drop ah -- Use FOR OBJ IN OBJS LOOP ......END LOOP; DECLARE CURSOR C_JOB ...

6. [ The Fourth Edition ] use getaddrinfo Set up tcp Basic connection properties

getaddrinfo getaddrinfo An important function of , It's very convenient to construct struct sockaddr_in object , Hide the tedious construction process getaddrinfo Both gethostbyname and ...

Believe in writing js Of , We all know window.onload Well , But not everyone knows DOMContentLoaded, In fact, even if you don't know , It's very likely that you use it a lot . In general ,DOMContentLoade ...

8. Linq grouping ,linq Method grouping

Group stay SQL Regular use , It's usually grouping one or more fields , Find the sum , Mean, etc . Linq Medium Groupby Methods also have this function . See code for specific implementation : Suppose there is a data set as follows : 01.public class ...

9. defer And async

defer: The script specified by this property will not be modified DOM, So code can safely delay execution . contain defer Attribute script Labels can be placed anywhere , On the page, parse to the script When labeling , Start downloading scripts , But it doesn't execute the script , until DOM ...