389 lines
18 KiB
Markdown
389 lines
18 KiB
Markdown
## Build code
|
||
### 前置作業
|
||
1. 要有NVIDIA GPU
|
||
2. 安裝NVIDIA GPU driver
|
||
3. 安裝[CUDA](https://developer.nvidia.com/cuda-downloads)
|
||
4. 安裝[cuDNN](https://developer.nvidia.com/rdp/cudnn-download)
|
||
5. 安裝[CMake](https://cmake.org/download/)
|
||
|
||
### CMake && Visual Studio
|
||
1. 下載OpenCV:[opencv](https://github.com/opencv/opencv)
|
||
2. 解壓縮後放到`D:\temp\build_opencv\opencv-4.5.3\source`
|
||
3. 建立`D:\temp\build_opencv\opencv-4.5.3\build`
|
||
4. 下載OpenCV contrib:[opencv_contrib](https://github.com/opencv/opencv_contrib)
|
||
5. 解壓縮後放到`D:\temp\build_opencv\opencv_contrib`
|
||
6. 打開cmake-gui
|
||
7. 如圖設定
|
||
![[Pasted image 20210818115317.png]]
|
||
8. 用`Add Entry`先加入以下define
|
||
![[Pasted image 20210818115507.png]]
|
||
如果是檔名,type就選FILEPATH,如果是目錄,type就選PATH
|
||
- PYTHON3_EXECUTABLE=C:/python39/python.exe
|
||
- PYTHON3_INCLUDE_DIR=C:/python39/include
|
||
- PYTHON3_LIBRARY=C:/python39/libs/python39.lib
|
||
- PYTHON3_NUMPY_INCLUDE_DIRS=C:/python39/Lib/site-packages/numpy/core/include
|
||
- PYTHON3_PACKAGES_PATH=C:/python39/Lib/site-packages
|
||
|
||
如果要build win32 + Python 3.6.3 x86的話,改為以下設定:
|
||
- PYTHON3_EXECUTABLE=C:/Python363/python.exe
|
||
- PYTHON3_INCLUDE_DIR=C:/Python363/include
|
||
- PYTHON3_LIBRARY=C:/Python363/libs/python36.lib
|
||
- PYTHON3_NUMPY_INCLUDE_DIRS=C:/Python363/Lib/site-packages/numpy/core/include
|
||
- PYTHON3_PACKAGES_PATH=C:/Python363/Lib/site-packages
|
||
9. 按Configure,會跳出一個視窗,platform選x64
|
||
![[Pasted image 20210818115809.png]]
|
||
10. 這些要打勾
|
||
- BUILD_opencv_world
|
||
- BUILD_opencv_python3
|
||
- OPENCV_DNN_CUDA
|
||
- OPENCV_PYTHON3_VERSION
|
||
- OPENCV_FORCE_PYTHON_LIBS
|
||
- OPENCV_ENABLE_NONFREE
|
||
- ENABLE_FAST_MATH
|
||
- WITH_CUDA
|
||
- WITH_OPENMP
|
||
- OPENCV_EXTRA_MODULES_PATH=D:/temp/build_opencv/opencv_contrib/modules
|
||
11. 再按一次Configure,必須沒有錯誤的跑完,像是
|
||
```
|
||
General configuration for OpenCV 4.5.3 =====================================
|
||
Version control: unknown
|
||
|
||
Extra modules:
|
||
Location (extra): D:/temp/build_opencv/opencv_contrib/modules
|
||
Version control (extra): 4.5.3-6-g907efb96
|
||
|
||
Platform:
|
||
Timestamp: 2021-08-18T03:40:06Z
|
||
Host: Windows 10.0.19043 AMD64
|
||
CMake: 3.21.1
|
||
CMake generator: Visual Studio 16 2019
|
||
CMake build tool: C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/MSBuild/Current/Bin/MSBuild.exe
|
||
MSVC: 1929
|
||
Configuration: Debug Release
|
||
|
||
CPU/HW features:
|
||
Baseline: SSE SSE2 SSE3
|
||
requested: SSE3
|
||
Dispatched code generation: SSE4_1 SSE4_2 FP16 AVX AVX2 AVX512_SKX
|
||
requested: SSE4_1 SSE4_2 AVX FP16 AVX2 AVX512_SKX
|
||
SSE4_1 (17 files): + SSSE3 SSE4_1
|
||
SSE4_2 (2 files): + SSSE3 SSE4_1 POPCNT SSE4_2
|
||
FP16 (1 files): + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 AVX
|
||
AVX (5 files): + SSSE3 SSE4_1 POPCNT SSE4_2 AVX
|
||
AVX2 (31 files): + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 FMA3 AVX AVX2
|
||
AVX512_SKX (7 files): + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 FMA3 AVX AVX2 AVX_512F AVX512_COMMON AVX512_SKX
|
||
|
||
C/C++:
|
||
Built as dynamic libs?: YES
|
||
C++ standard: 11
|
||
C++ Compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/VC/Tools/MSVC/14.29.30037/bin/Hostx64/x64/cl.exe (ver 19.29.30040.0)
|
||
C++ flags (Release): /DWIN32 /D_WINDOWS /W4 /GR /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi /fp:fast /EHa /wd4127 /wd4251 /wd4324 /wd4275 /wd4512 /wd4589 /MP /MD /O2 /Ob2 /DNDEBUG
|
||
C++ flags (Debug): /DWIN32 /D_WINDOWS /W4 /GR /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi /fp:fast /EHa /wd4127 /wd4251 /wd4324 /wd4275 /wd4512 /wd4589 /MP /MDd /Zi /Ob0 /Od /RTC1
|
||
C Compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/VC/Tools/MSVC/14.29.30037/bin/Hostx64/x64/cl.exe
|
||
C flags (Release): /DWIN32 /D_WINDOWS /W3 /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi /fp:fast /MP /MD /O2 /Ob2 /DNDEBUG
|
||
C flags (Debug): /DWIN32 /D_WINDOWS /W3 /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi /fp:fast /MP /MDd /Zi /Ob0 /Od /RTC1
|
||
Linker flags (Release): /machine:x64 /INCREMENTAL:NO
|
||
Linker flags (Debug): /machine:x64 /debug /INCREMENTAL
|
||
ccache: NO
|
||
Precompiled headers: NO
|
||
Extra dependencies: cudart_static.lib nppc.lib nppial.lib nppicc.lib nppidei.lib nppif.lib nppig.lib nppim.lib nppist.lib nppisu.lib nppitc.lib npps.lib cublas.lib cudnn.lib cufft.lib -LIBPATH:C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.4/lib/x64
|
||
3rdparty dependencies:
|
||
|
||
OpenCV modules:
|
||
To be built: aruco barcode bgsegm bioinspired calib3d ccalib core cudaarithm cudabgsegm cudacodec cudafeatures2d cudafilters cudaimgproc cudalegacy cudaobjdetect cudaoptflow cudastereo cudawarping cudev datasets dnn dnn_objdetect dnn_superres dpm face features2d flann fuzzy gapi hfs highgui img_hash imgcodecs imgproc intensity_transform line_descriptor mcc ml objdetect optflow phase_unwrapping photo plot python3 quality rapid reg rgbd saliency shape stereo stitching structured_light superres surface_matching text tracking ts video videoio videostab wechat_qrcode world xfeatures2d ximgproc xobjdetect xphoto
|
||
Disabled: -
|
||
Disabled by dependency: -
|
||
Unavailable: alphamat cvv freetype hdf java julia matlab ovis python2 python2 sfm viz
|
||
Applications: tests perf_tests apps
|
||
Documentation: NO
|
||
Non-free algorithms: NO
|
||
|
||
Windows RT support: NO
|
||
|
||
GUI:
|
||
Win32 UI: YES
|
||
VTK support: NO
|
||
|
||
Media I/O:
|
||
ZLib: build (ver 1.2.11)
|
||
JPEG: build-libjpeg-turbo (ver 2.1.0-62)
|
||
WEBP: build (ver encoder: 0x020f)
|
||
PNG: build (ver 1.6.37)
|
||
TIFF: build (ver 42 - 4.2.0)
|
||
JPEG 2000: build (ver 2.4.0)
|
||
OpenEXR: build (ver 2.3.0)
|
||
HDR: YES
|
||
SUNRASTER: YES
|
||
PXM: YES
|
||
PFM: YES
|
||
|
||
Video I/O:
|
||
DC1394: NO
|
||
FFMPEG: YES (prebuilt binaries)
|
||
avcodec: YES (58.134.100)
|
||
avformat: YES (58.76.100)
|
||
avutil: YES (56.70.100)
|
||
swscale: YES (5.9.100)
|
||
avresample: YES (4.0.0)
|
||
GStreamer: NO
|
||
DirectShow: YES
|
||
Media Foundation: YES
|
||
DXVA: YES
|
||
|
||
Parallel framework: Concurrency
|
||
|
||
Trace: YES (with Intel ITT)
|
||
|
||
Other third-party libraries:
|
||
Intel IPP: 2020.0.0 Gold [2020.0.0]
|
||
at: D:/temp/build_opencv/opencv-4.5.3/build/3rdparty/ippicv/ippicv_win/icv
|
||
Intel IPP IW: sources (2020.0.0)
|
||
at: D:/temp/build_opencv/opencv-4.5.3/build/3rdparty/ippicv/ippicv_win/iw
|
||
Lapack: NO
|
||
Eigen: NO
|
||
Custom HAL: NO
|
||
Protobuf: build (3.5.1)
|
||
|
||
NVIDIA CUDA: YES (ver 11.4, CUFFT CUBLAS)
|
||
NVIDIA GPU arch: 35 37 50 52 60 61 70 75 80 86
|
||
NVIDIA PTX archs:
|
||
|
||
cuDNN: YES (ver 8.2.2)
|
||
|
||
OpenCL: YES (NVD3D11)
|
||
Include path: D:/temp/build_opencv/opencv-4.5.3/source/3rdparty/include/opencl/1.2
|
||
Link libraries: Dynamic load
|
||
|
||
Python 3:
|
||
Interpreter: C:/python39/python.exe (ver 3.9.6)
|
||
Libraries: C:/python39/libs/python39.lib (ver 3.9.6)
|
||
numpy: C:/python39/Lib/site-packages/numpy/core/include (ver 1.19.5)
|
||
install path: C:/python39/Lib/site-packages/cv2/python-3.9
|
||
|
||
Python (for build): C:/python39/python.exe
|
||
|
||
Java:
|
||
ant: NO
|
||
JNI: NO
|
||
Java wrappers: NO
|
||
Java tests: NO
|
||
|
||
Install to: D:/temp/build_opencv/opencv-4.5.3/build/install
|
||
-----------------------------------------------------------------
|
||
|
||
Configuring done
|
||
```
|
||
12. 按下Generate按鈕就會生sln檔案。
|
||
|
||
|
||
### CMake by command
|
||
用command line的話就可以將多個平台一次編起來,不用一直改GUI。
|
||
寫了一個`build.bat`可以編譯不同版本與平台:
|
||
```bat
|
||
rem build.bat
|
||
echo on
|
||
rem build.bat
|
||
rem win32 ARCH=%1, win32/x64
|
||
rem 15 VS_CODE=%2, 15/16
|
||
rem 2017 VS_VERSION=%3, 2017/2019
|
||
rem DEBUG BUILD_TYPE=%4, DEBUG/RELEASE
|
||
rem "C:/Python363/python.exe" PYTHON3_EXE=%5
|
||
rem "C:/Python363/include" PYTHON3_INCLUDE=%6
|
||
rem "C:/Python363/libs/python36.lib" PYTHON3_LIB=%7
|
||
rem "C:/Python363/Lib/site-packages/numpy/core/include" PYTHON3_NP_INCLUDE=%8
|
||
rem "C:/Python363/Lib/site-packages" PYTHON3_PACKAGES=%9
|
||
rem 3.6.3 PY_VERSION=%10
|
||
rem 1 CLEAN_BUILD=%11, 1: Delete build folder, 0: Do nothing
|
||
|
||
set DO_CONFIG=1
|
||
set DO_BUILD=1
|
||
set ARCH=%1
|
||
set VS_CODE=%2
|
||
set VS_VERSION=%3
|
||
set BUILD_TYPE=%4
|
||
set PYTHON3_EXE=%5
|
||
set PYTHON3_INCLUDE=%6
|
||
set PYTHON3_LIB=%7
|
||
set PYTHON3_NP_INCLUDE=%8
|
||
set PYTHON3_PACKAGES=%9
|
||
set GENERATOR="Visual Studio %VS_CODE% %VS_VERSION%"
|
||
shift
|
||
set PY_VERSION=%9
|
||
set CV_VERSION=4.5.3
|
||
set CV_SOURCE="opencv-%CV_VERSION%\source"
|
||
set CV_BUILD=build\vs%VS_VERSION%.%ARCH%.%BUILD_TYPE%
|
||
set CV_EXTRA_MODULES="opencv_contrib\modules"
|
||
shift
|
||
set CLEAN_BUILD=%9
|
||
|
||
if %CLEAN_BUILD% == 1 (
|
||
rmdir /s /q %CV_BUILD%
|
||
)
|
||
|
||
if %DO_CONFIG% == 1 (
|
||
mkdir %CV_BUILD%
|
||
|
||
"C:\Program Files\CMake\bin\cmake.exe" ^
|
||
-B%CV_BUILD% ^
|
||
-H%CV_SOURCE% ^
|
||
-G%GENERATOR% ^
|
||
-A%ARCH% ^
|
||
-DCMAKE_BUILD_TYPE=%BUILD_TYPE% ^
|
||
-DOPENCV_EXTRA_MODULES_PATH=%CV_EXTRA_MODULES% ^
|
||
-DCMAKE_INSTALL_PREFIX=%CV_BUILD% ^
|
||
-DINSTALL_PYTHON_EXAMPLES=OFF ^
|
||
-DINSTALL_C_EXAMPLES=OFF ^
|
||
-DBUILD_opencv_python3=ON ^
|
||
-DPYTHON3_EXECUTABLE=%PYTHON3_EXE% ^
|
||
-DPYTHON3_INCLUDE_DIR=%PYTHON3_INCLUDE% ^
|
||
-DPYTHON3_LIBRARY=%PYTHON3_LIB% ^
|
||
-DPYTHON3_NUMPY_INCLUDE_DIRS=%PYTHON3_NP_INCLUDE% ^
|
||
-DPYTHON3_PACKAGES_PATH=%PYTHON3_PACKAGES% ^
|
||
-DOPENCV_PYTHON3_VERSION=%PY_VERSION% ^
|
||
-DOPENCV_FORCE_PYTHON_LIBS=ON ^
|
||
-DBUILD_opencv_world=ON ^
|
||
-DOPENCV_ENABLE_NONFREE=ON ^
|
||
-DENABLE_FAST_MATH=ON ^
|
||
-DWITH_OPENMP=ON ^
|
||
-DWITH_OPENGL=ON
|
||
)
|
||
|
||
if %DO_BUILD% == 1 (
|
||
"C:\Program Files\CMake\bin\cmake.exe" --build %CV_BUILD% --target INSTALL --config %BUILD_TYPE%
|
||
)
|
||
|
||
```
|
||
|
||
這樣以後就可以用參數的方法來設定,譬如要使用vs2019來編譯x64 release的話,就可以這樣下:
|
||
```bat
|
||
rem build_vs2019.x64.RELEASE.bat
|
||
echo off
|
||
rem ----------------------------------------------------------------------------------------------------
|
||
rem
|
||
rem x64, RELEASE, 2019, CLEAN
|
||
rem
|
||
set ARCH=x64
|
||
set VS_CODE=16
|
||
set VS_VERSION=2019
|
||
set BUILD_TYPE=RELEASE
|
||
set PYTHON3_EXE="C:/Python39/python.exe"
|
||
set PYTHON3_INCLUDE="C:/Python39/include"
|
||
set PYTHON3_LIB="C:/Python39/libs/python39.lib"
|
||
set PYTHON3_NP_INCLUDE="C:/Python39/Lib/site-packages/numpy/core/include"
|
||
set PYTHON3_PACKAGES="C:/Python39/Lib/site-packages"
|
||
set PY_VERSION=3.9
|
||
set CLEAN_BUILD=1
|
||
echo "============================================================"
|
||
echo "Build %ARCH%.%VS_VERSION%(%VS_CODE%).%BUILD_TYPE%, Python=%PY_VERSION%, CLEAN_BUILD=%CLEAN_BUILD%"
|
||
echo ""
|
||
call build.bat ^
|
||
%ARCH% %VS_CODE% %VS_VERSION% %BUILD_TYPE% %PYTHON3_EXE% ^
|
||
%PYTHON3_INCLUDE% %PYTHON3_LIB% %PYTHON3_NP_INCLUDE% %PYTHON3_PACKAGES% ^
|
||
%PY_VERSION% %CLEAN_BUILD%
|
||
rem ----------------------------------------------------------------------------------------------------
|
||
```
|
||
|
||
### 參考
|
||
- [Build OpenCV GPU Version On Windows 10](https://medium.com/chung-yi/build-opencv-gpu-version-on-windows-10-c37a33437525)
|
||
- [Cannot install openCV 3.1.0 with python3. CMAKE not including or linking python correctly](https://stackoverflow.com/questions/42638342/cannot-install-opencv-3-1-0-with-python3-cmake-not-including-or-linking-python)
|
||
- [在Windows上编译带CUDA(GPU)的OpenCV](https://shaogui.life/2021/03/08/%E5%9C%A8Windows%E4%B8%8A%E7%BC%96%E8%AF%91%E5%B8%A6CUDA(GPU)%E7%9A%84opencv/)
|
||
- [How to use OpenCV DNN Module with Nvidia GPU on Windows](https://learnopencv.com/how-to-use-opencv-dnn-module-with-nvidia-gpu-on-windows/)
|
||
- [Accelerate OpenCV 4.5.0 on Windows – build with CUDA and python bindings - James Bowley](https://jamesbowley.co.uk/accelerate-opencv-4-5-0-on-windows-build-with-cuda-and-python-bindings/#python_bindings)
|
||
|
||
## 影像處理
|
||
- sift
|
||
```python
|
||
def adjust_gamma(image, gamma=1.0):
|
||
invGamma = 1.0 / gamma
|
||
table = np.array([((i / 255.0) ** invGamma) * 255
|
||
for i in np.arange(0, 256)]).astype("uint8")
|
||
|
||
return cv2.LUT(image, table)
|
||
|
||
|
||
def sift_compare(path_a, path_b):
|
||
'''
|
||
Use SIFT features to measure image similarity
|
||
@args:
|
||
{str} path_a: the path to an image file
|
||
{str} path_b: the path to an image file
|
||
@returns:
|
||
TODO
|
||
'''
|
||
# initialize the sift feature detector
|
||
orb = cv2.ORB_create()
|
||
|
||
# get the images
|
||
img_a = cv2.imread(path_a)
|
||
img_b = cv2.imread(path_b)
|
||
img_a = adjust_gamma(img_a, 0.1)
|
||
img_b = adjust_gamma(img_b, 0.1)
|
||
|
||
# find the keypoints and descriptors with SIFT
|
||
kp_a, desc_a = orb.detectAndCompute(img_a, None)
|
||
kp_b, desc_b = orb.detectAndCompute(img_b, None)
|
||
# print(f'len kp_a = {len(kp_a)}, len desc_a = {len(desc_a)}')
|
||
# print(f'type kp_b = {type(kp_b)}, type desc_b = {type(desc_b)}')
|
||
# print(f'len kp_b = {len(kp_b)}, len desc_b = {len(desc_b) if desc_b else 0}')
|
||
|
||
if desc_a is None or desc_b is None:
|
||
# rr.LOG('Error: desc_a = {}, desc_b = {}'.format(type(desc_a), type(desc_b)))
|
||
# rr.LOG('Error: Return score 0.')
|
||
return 0
|
||
|
||
# Initialize the bruteforce matcher
|
||
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
|
||
|
||
# match.distance is a float between {0:100} - lower means more similar
|
||
matches = bf.match(desc_a, desc_b)
|
||
similar_regions = [i for i in matches if i.distance < 70]
|
||
|
||
# print('Length of similar_regions = {}'.format(len(similar_regions)))
|
||
# print('Length of matches = {}'.format(len(matches)))
|
||
|
||
sorted_matches = sorted(matches, key = lambda x:x.distance)
|
||
good_matches = sorted_matches[:int(len(sorted_matches) * 0.5)]
|
||
similar_regions2 = [i for i in good_matches if i.distance < 70]
|
||
# print('Length of good_matches = {}'.format(len(good_matches)))
|
||
|
||
if len(matches) == 0:
|
||
return 0
|
||
return len(similar_regions) / len(matches)
|
||
```
|
||
|
||
### Color tempertature
|
||
code
|
||
```
|
||
img1 = cv2.imread(file)
|
||
B, G, R = cv2.split(img1)
|
||
avgB = cv2.mean(B)[0]
|
||
avgG = cv2.mean(G)[0]
|
||
avgR = cv2.mean(R)[0]
|
||
|
||
# X = avgR * -0.14282 + avgG * 1.54924 + avgB * -0.95641
|
||
# Y = avgR * -0.32466 + avgG * 1.57837 + avgB * -0.73191
|
||
# Z = avgR * -0.68202 + avgG * 0.77073 + avgB * 0.56332
|
||
X = 2.789 * avgR + 1.7517 * avgG + 1.1302 * avgB
|
||
Y = 1 * avgR + 4.5907 * avgG + 0.0601 * avgB
|
||
Z = 0 * avgR + 0.0565 * avgG + 5.5943 * avgB
|
||
x = X / (X + Y + Z)
|
||
y = Y / (X + Y + Z)
|
||
n = (x - 0.3320) / (0.1858 - y)
|
||
# n = (0.23881 * avgR + 0.25499 * avgG + -0.58291 * avgB) / (0.11109 * avgR + -0.85406 * avgG + 0.52289 * avgB)
|
||
CCT = 449 * pow(n, 3) + 3525 * pow(n, 2) + 6823.3 * n + 5520.33
|
||
# CCT = 437 * pow(n, 3) + 3601 * pow(n, 2) + 6831 * n + 5517
|
||
|
||
# print(f'x = {x}')
|
||
# print(f'y = {y}')
|
||
# print(f'n = {n}')
|
||
print(f'{file}: CCT = {CCT}')
|
||
```
|
||
|
||
- [How to Calculate the Color Temperature / Tint of the Colors in an Image?](https://dsp.stackexchange.com/questions/8949/how-to-calculate-the-color-temperature-tint-of-the-colors-in-an-image)
|
||
- [Calculating Color Temperature and Illuminance using the TAOS TCS3414CS Digital Color Sensor_](https://ams.com/documents/20143/80162/TCS34xx_AN000517_1-00.pdf)
|
||
- [Java RGB转色温(CCT)](https://www.codeleading.com/article/16404945886/)
|
||
- [Calculate color temperature (CCT) from CIE 1931 xy coordinates](https://www.waveformlighting.com/tech/calculate-color-temperature-cct-from-cie-1931-xy-coordinates)
|
||
- [OpenCV: Color conversions](https://docs.opencv.org/3.4/de/d25/imgproc_color_conversions.html)
|
||
- [sRGB色彩空間 - 維基百科,自由的百科全書](https://zh.wikipedia.org/wiki/SRGB%E8%89%B2%E5%BD%A9%E7%A9%BA%E9%97%B4)
|
||
- [Color temperature - Wikipedia](https://en.wikipedia.org/wiki/Color_temperature#Approximation)
|
||
- [What color is a blackbody? - some pixel rgb values](http://www.vendian.org/mncharity/dir3/blackbody/) |