Skip to content

Commit 5923b8c

Browse files
committed
init
1 parent efca4e0 commit 5923b8c

File tree

5 files changed

+330
-2
lines changed

5 files changed

+330
-2
lines changed

Makefile

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
LIBROOT=/opt/intel/system_studio_2018/compilers_and_libraries_2018.2.199/linux
2+
IPPROOT=${LIBROOT}/ipp
3+
MKLROOT=${LIBROOT}/mkl
4+
COMROOT=${LIBROOT}/compiler
5+
6+
all: resize_fft
7+
8+
resize_fft: resize_fft.cpp
9+
@g++ resize_fft.cpp -g -std=c++11 -I${IPPROOT}/include -I${MKLROOT}/include -L./intel64 -L${MKLROOT}/lib/intel64 -L${COMROOT}/lib/intel64 -Wl,-rpath,./intel64 -Wl,-rpath,${MKLROOT}/lib/intel64 -Wl,-rpath,${COMROOT}/lib/intel64 -Wl,--no-as-needed -lipp_rt -lmkl_rt -lpthread -lm -ldl `pkg-config --cflags --libs opencv` -o resize_fft
10+
11+
clean:
12+
@rm resize_fft

README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
# py-ipp-mkl
2-
Tutorial for using Intel IPP / Intel MKL in Python
1+
# py-ipp-mkl Tutorial
2+
***
3+
WIP

ipp_functions.txt

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
ippSetCpuFeatures
2+
ippSetNumThreads
3+
ippiResizeGetSize_8u
4+
ippsMalloc_8u
5+
ippiResizeLinearInit_8u
6+
ippiResizeGetBufferSize_8u
7+
ippiResizeLinear_8u_C1R
8+
ippsFree

resize_fft.cpp

+184
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
/*******************************************************************************
2+
* Copyright 2017-2018 Intel Corporation
3+
* All Rights Reserved.
4+
*
5+
* If this software was obtained under the Intel Simplified Software License,
6+
* the following terms apply:
7+
*
8+
* The source code, information and material ("Material") contained herein is
9+
* owned by Intel Corporation or its suppliers or licensors, and title to such
10+
* Material remains with Intel Corporation or its suppliers or licensors. The
11+
* Material contains proprietary information of Intel or its suppliers and
12+
* licensors. The Material is protected by worldwide copyright laws and treaty
13+
* provisions. No part of the Material may be used, copied, reproduced,
14+
* modified, published, uploaded, posted, transmitted, distributed or disclosed
15+
* in any way without Intel's prior express written permission. No license under
16+
* any patent, copyright or other intellectual property rights in the Material
17+
* is granted to or conferred upon you, either expressly, by implication,
18+
* inducement, estoppel or otherwise. Any license under such intellectual
19+
* property rights must be express and approved by Intel in writing.
20+
*
21+
* Unless otherwise agreed by Intel in writing, you may not remove or alter this
22+
* notice or any other notice embedded in Materials by Intel or Intel's
23+
* suppliers or licensors in any way.
24+
*
25+
*
26+
* If this software was obtained under the Apache License, Version 2.0 (the
27+
* "License"), the following terms apply:
28+
*
29+
* You may not use this file except in compliance with the License. You may
30+
* obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
31+
*
32+
*
33+
* Unless required by applicable law or agreed to in writing, software
34+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
35+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
36+
*
37+
* See the License for the specific language governing permissions and
38+
* limitations under the License.
39+
*******************************************************************************/
40+
41+
#include <iostream>
42+
#include <string>
43+
44+
#include "opencv2/core/core.hpp"
45+
#include "opencv2/imgcodecs.hpp"
46+
#include "opencv2/highgui/highgui.hpp"
47+
48+
#include <ippcore.h>
49+
#include <ippi.h>
50+
#include <ipps.h>
51+
#include <ippcc.h>
52+
#include <ippcv.h>
53+
#include <mkl.h>
54+
55+
using namespace cv;
56+
using namespace std;
57+
58+
void resize(const uchar* img_src, int src_height, int src_width, uchar* img_dst, int dst_height, int dst_width)
59+
{
60+
// ippSetCpuFeatures(cpuFeatures);
61+
// ippSetNumThreads(numThr);
62+
63+
IppiSize ssize = {src_width, src_height};
64+
IppiRect srect = {0, 0, src_width, src_height};
65+
IppiSize dsize = {dst_width, dst_height};
66+
IppiRect drect = {0, 0, dst_width, dst_height};
67+
68+
int specSize = 0;
69+
int initBufSize = 0;
70+
ippiResizeGetSize_8u(ssize, dsize, ippLinear, 0, &specSize, &initBufSize);
71+
IppiResizeSpec_32f* pSpec = (IppiResizeSpec_32f*)ippsMalloc_8u(specSize);
72+
ippiResizeLinearInit_8u(ssize, dsize, pSpec);
73+
int bufSize = 0;
74+
ippiResizeGetBufferSize_8u(pSpec, dsize, 3, &bufSize);
75+
Ipp8u* pBuffer = ippsMalloc_8u(bufSize);
76+
IppiPoint p = {0, 0};
77+
ippiResizeLinear_8u_C1R((const Ipp8u*)img_src, src_width, (Ipp8u*)img_dst, dst_width, p, dsize, ippBorderRepl, 0, pSpec, pBuffer);
78+
ippsFree(pSpec);
79+
ippsFree(pBuffer);
80+
}
81+
82+
void fft(const uchar* img_data, int height, int width, uchar* img_fft_data)
83+
{
84+
/* Init tmp resourses */
85+
double *x_real = (double*)mkl_malloc(width*height*sizeof(double), 64);
86+
double *x_fft = (double*)mkl_malloc(width*height*sizeof(double), 64);
87+
MKL_Complex16 *x_out = (MKL_Complex16*)mkl_malloc((width/2+1)*height*sizeof(MKL_Complex16), 64);
88+
89+
/* Configure FFT handler */
90+
DFTI_DESCRIPTOR_HANDLE hand = 0;
91+
MKL_LONG N[2];
92+
N[0] = height;
93+
N[1] = width;
94+
DftiCreateDescriptor(&hand, DFTI_DOUBLE, DFTI_REAL, 2, N);
95+
DftiSetValue(hand, DFTI_PLACEMENT, DFTI_NOT_INPLACE);
96+
DftiSetValue(hand, DFTI_CONJUGATE_EVEN_STORAGE, DFTI_COMPLEX_COMPLEX);
97+
MKL_LONG rs[3];
98+
rs[0] = 0;
99+
rs[1] = width;
100+
rs[2] = 1;
101+
MKL_LONG cs[3];
102+
cs[0] = 0;
103+
cs[1] = width/2+1;
104+
cs[2] = 1;
105+
DftiSetValue(hand, DFTI_INPUT_STRIDES, rs);
106+
DftiSetValue(hand, DFTI_OUTPUT_STRIDES, cs);
107+
DftiSetValue(hand, DFTI_FORWARD_SCALE, (double)1.0/(width*height));
108+
DftiCommitDescriptor(hand);
109+
110+
/* Load image data from 8U to double array */
111+
for (int i = 0; i < height; ++i)
112+
{
113+
for (int j = 0; j < width; ++j)
114+
{
115+
// method 1: 输入数据乘以(-1)^(i+j),即可中心化
116+
x_real[i*width+j] = pow(-1, i + j) * (double)img_data[i*width+j];
117+
}
118+
}
119+
120+
/* Perform FFT calculation */
121+
DftiComputeForward(hand, x_real, x_out);
122+
123+
/* Extend compressed FFT results into full matrix */
124+
double min = numeric_limits<double>::max();
125+
double max = 0;
126+
for (int j = 0; j < width; j++)
127+
{
128+
for (int i = 0; i < height; i++)
129+
{
130+
MKL_Complex16 val;
131+
if(j < width/2+1)
132+
{
133+
val.real = x_out[i*(width/2+1)+j].real;
134+
val.imag = x_out[i*(width/2+1)+j].imag;
135+
double amp = log(sqrt(val.real*val.real+val.imag*val.imag));
136+
x_fft[i*width+j] = amp;
137+
if(amp < min)
138+
min = amp;
139+
if(amp > max)
140+
max = amp;
141+
}
142+
else
143+
{
144+
if(i == 0)
145+
x_fft[j] = x_fft[width-j];
146+
else
147+
x_fft[i*width+j] = x_fft[(height-i)*width+width-j];
148+
}
149+
}
150+
}
151+
152+
/* Normalize FFT results for visualization */
153+
for (int i = 0; i < height*width; i++)
154+
img_fft_data[i] = /*img_fft_data[i]>0?255:0;*/ 255.0 * (x_fft[i] - min) / (double)(max-min);
155+
156+
/* Release tmp resources */
157+
mkl_free(x_out);
158+
mkl_free(x_fft);
159+
mkl_free(x_real);
160+
}
161+
162+
int main(int argc, char** argv)
163+
{
164+
Mat img = imread("testimg.jpg", IMREAD_GRAYSCALE);
165+
if(img.empty())
166+
{
167+
printf("Error loading image\n");
168+
exit(1);
169+
}
170+
int factor = 2;
171+
int width_dst = img.cols / factor;
172+
int height_dst = img.rows / factor;
173+
Mat img_resize = Mat::zeros(height_dst, width_dst, CV_8UC1);
174+
Mat img_fft = Mat::zeros(img_resize.rows, img_resize.cols, CV_8UC1);
175+
176+
resize(img.data, img.rows, img.cols, img_resize.data, img_resize.rows, img_resize.cols);
177+
fft(img_resize.data, img_resize.rows, img_resize.cols, img_fft.data);
178+
imshow("img", img);
179+
imshow("resize", img_resize);
180+
imshow("fft", img_fft);
181+
waitKey(0);
182+
183+
return 0;
184+
}

resize_fft.py

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#!/usr/bin/env python3
2+
# encoding: utf-8
3+
4+
""" A tutorial for using IPP/MKL C API functions in Python """
5+
6+
__author__ = 'Jing Xu'
7+
__email__ = '[email protected]'
8+
9+
import math
10+
import numpy as np
11+
import cv2
12+
from ctypes import *
13+
14+
class IppiSize(Structure):
15+
_fields_ = [("width", c_int),
16+
("height", c_int)]
17+
18+
class IppiRect(Structure):
19+
_fields_ = [("x", c_int),
20+
("y", c_int),
21+
("width", c_int),
22+
("height", c_int)]
23+
24+
class IppiPoint(Structure):
25+
_fields_ = [("x", c_int),
26+
("y", c_int)]
27+
28+
class MKL_Complex16(Structure):
29+
_fields_ = [("real", c_double),
30+
("imag", c_double)]
31+
32+
# Load dynamic libraries
33+
ipp = cdll.LoadLibrary("./intel64/libipp_rt.so")
34+
mkl = cdll.LoadLibrary("/opt/intel/system_studio_2018/compilers_and_libraries_2018.2.199/linux/mkl/lib/intel64/libmkl_rt.so")
35+
36+
def resize(img_src, img_dst):
37+
ssize = IppiSize(img_src.shape[1], img_src.shape[0])
38+
srect = IppiRect(0, 0, img_src.shape[1], img_src.shape[0])
39+
dsize = IppiSize(img_dst.shape[1], img_dst.shape[0])
40+
drect = IppiRect(0, 0, img_dst.shape[1], img_dst.shape[0])
41+
specSize = c_int(0)
42+
initBufSize = c_int(0)
43+
ipp.ippiResizeGetSize_8u(ssize, dsize, 2, 0, byref(specSize), byref(initBufSize))
44+
pSpec = ipp.ippsMalloc_8u(specSize)
45+
ipp.ippiResizeLinearInit_8u(ssize, dsize, pSpec)
46+
bufSize = c_int(0)
47+
ipp.ippiResizeGetBufferSize_8u(pSpec, dsize, 3, byref(bufSize))
48+
pBuffer = ipp.ippsMalloc_8u(bufSize)
49+
p = IppiPoint(0, 0)
50+
ipp.ippiResizeLinear_8u_C1R(img_src.ctypes.data_as(POINTER(c_ubyte)), img_src.shape[1], img_dst.ctypes.data_as(POINTER(c_ubyte)), img_dst.shape[1], p, dsize, 1, 0, c_void_p(pSpec), c_void_p(pBuffer))
51+
ipp.ippsFree(pSpec)
52+
ipp.ippsFree(pBuffer)
53+
54+
def fft(img_data):
55+
height = img_data.shape[0]
56+
width = img_data.shape[1]
57+
58+
cdouble_imgsize = c_double * img_data.size
59+
ccomplex_imgsize = MKL_Complex16 * img_data.size
60+
x_real = cdouble_imgsize()
61+
x_out = ccomplex_imgsize()
62+
x_fft = np.zeros((height, width, 1), dtype=np.float64)
63+
64+
# Configure FFT handler
65+
hand = c_void_p()
66+
clong2 = c_long * 2
67+
clong3 = c_long * 3
68+
N = clong2()
69+
N[0] = height
70+
N[1] = width
71+
mkl.DftiCreateDescriptor(byref(hand), 36, 33, 2, N)
72+
mkl.DftiSetValue(hand, 11, 44)
73+
mkl.DftiSetValue(hand, 10, 39)
74+
rs = clong3()
75+
rs[0] = 0
76+
rs[1] = width
77+
rs[2] = 1
78+
cs = clong3()
79+
cs[0] = 0
80+
cs[1] = int(width/2+1)
81+
cs[2] = 1
82+
mkl.DftiSetValue(hand, 12, rs)
83+
mkl.DftiSetValue(hand, 13, cs)
84+
mkl.DftiSetValue(hand, 4, c_double(1.0/img_data.size))
85+
mkl.DftiCommitDescriptor(hand)
86+
87+
# Load image data from 8U to double array
88+
for i in range(0, img_data.shape[0]):
89+
for j in range(0, img_data.shape[1]):
90+
x_real[i*img_data.shape[1]+j] = c_double(math.pow(-1, i+j) * img_data[i][j])
91+
92+
# Perform FFT calculation
93+
mkl.DftiComputeForward(hand, x_real, x_out)
94+
95+
# Expand compressed FFT results into full matrix
96+
for j in range(0, width):
97+
for i in range(0, height):
98+
if j < width/2+1:
99+
val = MKL_Complex16()
100+
val.real = x_out[i*int(width/2+1)+j].real
101+
val.imag = x_out[i*int(width/2+1)+j].imag;
102+
x_fft[i][j] = math.log(math.sqrt(val.real*val.real+val.imag*val.imag))
103+
else:
104+
if i == 0:
105+
x_fft[0][j] = x_fft[0][width-j]
106+
else:
107+
x_fft[i][j] = x_fft[height-i][width-j]
108+
109+
# Normalize FFT results for visualization
110+
fft_min = x_fft.min()
111+
fft_max = x_fft.max()
112+
x_fft = 255.0 * (x_fft - fft_min) / (fft_max - fft_min)
113+
return x_fft.astype(np.uint8)
114+
115+
img = cv2.imread("testimg.jpg", cv2.IMREAD_GRAYSCALE)
116+
img_resize = np.zeros((int(img.shape[0]/2), int(img.shape[1]/2), 1), dtype=np.uint8)
117+
resize(img, img_resize)
118+
img_fft = fft(img_resize)
119+
cv2.imshow('img', img)
120+
cv2.imshow('img_resize', img_resize)
121+
cv2.imshow('img_fft', img_fft)
122+
cv2.waitKey(0)
123+
cv2.destroyAllWindows()

0 commit comments

Comments
 (0)