From 8cdfebe75d9c0801ea2d4bbaca7102450e24360b Mon Sep 17 00:00:00 2001 From: meshtag Date: Wed, 20 Apr 2022 11:41:22 +0800 Subject: [PATCH 1/4] First draft for GIL comparison --- CMakeLists.txt | 4 ++ README.md | 12 ++++ .../ImageProcessing/Images/gil_sample.png | Bin 0 -> 3258 bytes comparison/CMakeLists.txt | 1 + comparison/ImageProcessing/CMakeLists.txt | 16 +++++ .../ImageProcessing/boost_gil_conv2d.cpp | 63 ++++++++++++++++++ 6 files changed, 96 insertions(+) create mode 100644 benchmarks/ImageProcessing/Images/gil_sample.png create mode 100644 comparison/CMakeLists.txt create mode 100644 comparison/ImageProcessing/CMakeLists.txt create mode 100644 comparison/ImageProcessing/boost_gil_conv2d.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index cc561ab4..59ef474f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -136,3 +136,7 @@ if (BUILD_TESTS) enable_testing() add_subdirectory(tests) endif() + +if (BUILD_COMPARISONS) + add_subdirectory(comparison) +endif() diff --git a/README.md b/README.md index 8de2b5f3..30971fa1 100644 --- a/README.md +++ b/README.md @@ -129,3 +129,15 @@ $ cmake --build . -- $ ninja test ``` +## Comparisons + +``` +$ cd buddy-benchmark +$ mkdir build && cd build +$ cmake -G Ninja .. \ + -DBUILD_COMPARISONS=ON \ + -DOpenCV_DIR=/PATH/TO/OPENCV/BUILD/ \ + -DBUDDY_OPT_BUILD_DIR=/PATH/TO/BUDDY-MLIR/BUILD/ +$ ninja boost_gil_conv2d +$ cd bin && ./boost_gil_conv2d +``` diff --git a/benchmarks/ImageProcessing/Images/gil_sample.png b/benchmarks/ImageProcessing/Images/gil_sample.png new file mode 100644 index 0000000000000000000000000000000000000000..32b9c32323c2ff0a3ed6ca947bed38747bb42406 GIT binary patch literal 3258 zcmZ`*c~sKb9{*vW;*z-Gu8>-&p-8Tn#o}7&VB(TmiHhRBVP+O8u30virfs8QnUp?_ z6iuhbW>O=qWXvTkr^%H}$4OGdTppcw&b;&fc<0=EzW08=pYQ$NbMJRMPxf|KR?t-d z06^K(!{sOd$l#=N6eMK;jUPv?r34&B@FD;J??=TADnzgf z7@l6Pax+jUL>H0%QuDHu1xifurho=&)2{=7qPC|CfpU6$al+};lmlEgba1d#Q&g^s z{rlQ)YA}BxsFG#su+aE0Z|v7N$l>4B%ojpmo!)y4`26re#&+g}|IbCfrlmDsuYo^L zlE|a~qAJG*KGhw$UtrrPU4C^hs2&&~Ky(MTr#aP~f2nASX14uztdI6@zw`lN>$MsH zgQ-Z*r;IZlWllH5u~{0V%6MLws0Ollg+ovrzkpm@Z&N3&u6R|IwsL%FwK8d8sE|LZ zZG-0^>2NL^*@9jk*|KOQ zN=Lg41TE-=Mz`A$2EC{2NoxZGUG$={e@%>_KPZ*#70tA6PzSTUZ}{SO=DyPMJ!`nH z`fn#V6p?~5IB15(p*5b zyBF+BXT>l}RxRwfBx5tKwDb~M!hCpJx=@mtP`ztSC%g^LE}k;ZDfT-huW?x93%75N zVmfN8p7RZ;eH&5W1apzjcs} zz~p2?lh^eba&kz>O-wTD_xm&K=-t}3Z(kBz!;Ez48OIM-=N`Cxp^|iCH$3kQ8nt5F zBRrjEM4&ToB2k2Xt4mB9jXd@Rb$@vs{c#~XoJ7klI}~revNLzQs`J+x={Lp_%(hMF z5`)!nYx|K;R$Zzz4-~C=#=iECoQn6WW*j32N?To~zPWE|0I5IGesWkmTPH)$}6cci?Wm+?2 zMMmnJ6BBlf=YB9sMd{~_GkC;2uhdCiL2^+Q@2{8=L@wp41PT2W$K?^V_o=W_zBPT{ zOlr7l53A4rt)|Z-IrjF8s3V}yRj(}$oD;IzWa#yfl^Ed=-jG#1wH@T9BrA#Qti;cn zcb`3yO0VHu4c0FA5Y3Q}sVXpx@zwsm7k7Kpu)WHJc z%$zBi%Yo*_9hmCuATFy3BG@yIi(^I#wozFq%6?*(CjPOmjh|3m-uB$0vw|e%AXN~O z^Cp}+L~acHFHs6Wtis@~O9$zMsgU9GoIq8c-0+*@Id5!(n`ONYk;PvmbEFfB*s<0! ze1?v-8fu_a4q84Zh%cO5*ySDx%K~nwM` z1VNfC7Cb_$_pu(=A{FLxoKb+d*O!f$SF@7d36@6C{2otRP?+6O1c+)3QOh#SEyA*t z9X;@GJaWK!B^n-!a$ujj5t5Ks(jtGm()b|OctQ?bJEF_+dJtcpiwF}0?;yCGKmDhL zL57}&zGY<0tt~}D*ElLJ$#B;;HCGISRd{s!!n9q6i?Wa~+i7e61TVd`tm$3#_~C=_ z9B#-Czl0$s*Hmrf5VQI^Drx@&?>y+)>y>y7*=w$=tiK>m zeyGR^qHyNkY1cGflqfAG#sOh*z;O;kpmi_^vxZM2{jzsvwpc-!h_5P9o#X zvRBLZ+ zz@({s}` z#Zxa>#C;m>AUAHd_k_qrEXJ}S-)oh{caJu!Iv&$ZSUB1sE0NJn5@-lRV#ZcHpwL6{ zN3O6l4Wa^HD(IdJs2*hbfN2e>98So=AmF@?^!h!u7+l?e|>;m58qU!})s&?;1C$--9Gbt+l39&Y-pC>W)I$ zu$@i5THkbJJOHHlChG7ueFid>kk6h9H z;^`@aFvB**p^>e3PvIhTe=S@#(_lG>J&Vo)0XMt2L^P?W5>vxP)n9Jx#9`6vEk(B}uMkj{Gl zo%*P9{Ju+q$Lws#8c(cHqCM6eCtcd0OAGyJ;l6uACX6|w=MOhlPJ zJv-zq<8$Sg9K?I#4shMUgXslr(nBO*o@L7&{%nLh^PTf{gRgoItLTzXmIYgj7)^>( z@A_0(i0~f-w?;&r4jGsw@F>+B4&xFMiw^?*J5B~hc4?S zlJAuQbbH#d8gu1z=4MasAn*D7({sFR#R)&yy2ha$yy^>3G{eK{W@s??s{{&VcpKIO zKYdy%RdkeD9|pbG8&ek=N_O`b5>*7FDrO>6{vHF7#6n&2&hYjd38(oV_Ic+|m$=W4J7tpOtouLi~c)RmNoz!)zf7C;X>p{ZIQ!`>;(H zrw<2pP8UcUW>bc1AR~gxpy9$(Xi@@TF<5If#!)&b7+W0H4!6(R0)xR}FsIGt#Q&oZ zpBNDxneqP>pp270NEP7UEij@ZBXQKYBsvvHOGr(kg-1t5(;`}!Om8VdMs6VtOh%iI##+ Zm12_sYa2Jc*>_R|;OXk^(nJhp{Tm{no$mku literal 0 HcmV?d00001 diff --git a/comparison/CMakeLists.txt b/comparison/CMakeLists.txt new file mode 100644 index 00000000..6071631f --- /dev/null +++ b/comparison/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(ImageProcessing) diff --git a/comparison/ImageProcessing/CMakeLists.txt b/comparison/ImageProcessing/CMakeLists.txt new file mode 100644 index 00000000..32a52fb2 --- /dev/null +++ b/comparison/ImageProcessing/CMakeLists.txt @@ -0,0 +1,16 @@ +find_package(OpenCV REQUIRED) +include_directories(${OpenCV_INCLUDE_DIRS}) + +add_executable(boost_gil_conv2d boost_gil_conv2d.cpp) +find_package(Boost) +if(Boost_FOUND) + message(STATUS "boost include path is : ${Boost_INCLUDE_DIRS}") + include_directories(${Boost_INCLUDE_DIRS}) +else() + message(WARNING "boost not found.") +endif() +find_package(PNG REQUIRED) +target_link_libraries(boost_gil_conv2d + PNG::PNG + ${BOOST_LIBRARIES} + ${OpenCV_LIBS}) diff --git a/comparison/ImageProcessing/boost_gil_conv2d.cpp b/comparison/ImageProcessing/boost_gil_conv2d.cpp new file mode 100644 index 00000000..3e9369ed --- /dev/null +++ b/comparison/ImageProcessing/boost_gil_conv2d.cpp @@ -0,0 +1,63 @@ +//===- boost_gil_conv2d.cpp -------------------------------------------===// +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//===----------------------------------------------------------------------===// +// +// This file implements an example for depicting the use of Boost GIL's 2D Convolution API. +// +//===----------------------------------------------------------------------===// + +#include "ImageProcessing/Kernels.h" +#include +#include +#include +#include +#include + +namespace gil = boost::gil; + +void fill_gil_view_with_opencv_mat(cv::Mat opencv_mat, + gil::gray8_view_t gil_view) { + for (int i = 0; i < opencv_mat.rows; i++) + for (int j = 0; j < opencv_mat.cols; j++) + gil_view(j, i) = opencv_mat.at(i, j); +} + +int main(int argc, char *argv[]) { + // Read input image using opencv's imread() + cv::Mat opencv_image = cv::imread(argv[1], cv::IMREAD_GRAYSCALE); + + // Declare input image + gil::gray8_image_t image(opencv_image.cols, opencv_image.rows); + + // Fill GIL image view with image read using opencv's imread() + fill_gil_view_with_opencv_mat(opencv_image, gil::view(image)); + + // Declare output image + gil::gray8_image_t output(image.dimensions()); + + // Create a 2D GIL kernel + gil::detail::kernel_2d kernel(sobel3x3KernelAlign, 9, 1, 1); + + clock_t start, end; + start = clock(); + // Apply 2D convolution between input image and kernel + gil::detail::convolve_2d(gil::view(image), kernel, gil::view(output)); + end = clock(); + std::cout << "Execution time: " << (double)(end - start) / CLOCKS_PER_SEC + << " s" << std::endl; + + // Save obtained image + gil::write_view(argv[2], gil::view(output), gil::png_tag{}); +} From f20b7974441327b99af46b8a3c59573455f2104a Mon Sep 17 00:00:00 2001 From: meshtag Date: Wed, 20 Apr 2022 11:44:40 +0800 Subject: [PATCH 2/4] Add CLI example and apply clang-format Improve formatting in boost_gil_conv2d.cpp --- README.md | 1 + comparison/ImageProcessing/boost_gil_conv2d.cpp | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 30971fa1..fcea7919 100644 --- a/README.md +++ b/README.md @@ -141,3 +141,4 @@ $ cmake -G Ninja .. \ $ ninja boost_gil_conv2d $ cd bin && ./boost_gil_conv2d ``` +Ex. `./boost_gil_conv2d ../../benchmarks/ImageProcessing/Images/gil_sample.png gil_output.png` diff --git a/comparison/ImageProcessing/boost_gil_conv2d.cpp b/comparison/ImageProcessing/boost_gil_conv2d.cpp index 3e9369ed..763600ce 100644 --- a/comparison/ImageProcessing/boost_gil_conv2d.cpp +++ b/comparison/ImageProcessing/boost_gil_conv2d.cpp @@ -1,4 +1,4 @@ -//===- boost_gil_conv2d.cpp -------------------------------------------===// +//===- boost_gil_conv2d.cpp -----------------------------------------------===// // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,7 +14,8 @@ // //===----------------------------------------------------------------------===// // -// This file implements an example for depicting the use of Boost GIL's 2D Convolution API. +// This file implements an example for depicting the use of Boost GIL's 2D +// Convolution API. // //===----------------------------------------------------------------------===// From 0f4ed78c99d8ea152126ed8311e6c6eb0b2d5018 Mon Sep 17 00:00:00 2001 From: meshtag Date: Tue, 26 Apr 2022 22:40:56 +0800 Subject: [PATCH 3/4] Add more comparison examples --- comparison/CMakeLists.txt | 17 +++- comparison/ImageProcessing/CMakeLists.txt | 16 ---- comparison/README.md | 70 +++++++++++++++ .../boost_gil_conv2d.cpp | 0 comparison/gen-conv-models.py | 89 +++++++++++++++++++ comparison/onnxruntime-conv2d.py | 33 +++++++ comparison/pytorch-conv2d.py | 68 ++++++++++++++ comparison/tf-conv2d.py | 62 +++++++++++++ 8 files changed, 338 insertions(+), 17 deletions(-) delete mode 100644 comparison/ImageProcessing/CMakeLists.txt create mode 100644 comparison/README.md rename comparison/{ImageProcessing => }/boost_gil_conv2d.cpp (100%) create mode 100644 comparison/gen-conv-models.py create mode 100644 comparison/onnxruntime-conv2d.py create mode 100644 comparison/pytorch-conv2d.py create mode 100644 comparison/tf-conv2d.py diff --git a/comparison/CMakeLists.txt b/comparison/CMakeLists.txt index 6071631f..32a52fb2 100644 --- a/comparison/CMakeLists.txt +++ b/comparison/CMakeLists.txt @@ -1 +1,16 @@ -add_subdirectory(ImageProcessing) +find_package(OpenCV REQUIRED) +include_directories(${OpenCV_INCLUDE_DIRS}) + +add_executable(boost_gil_conv2d boost_gil_conv2d.cpp) +find_package(Boost) +if(Boost_FOUND) + message(STATUS "boost include path is : ${Boost_INCLUDE_DIRS}") + include_directories(${Boost_INCLUDE_DIRS}) +else() + message(WARNING "boost not found.") +endif() +find_package(PNG REQUIRED) +target_link_libraries(boost_gil_conv2d + PNG::PNG + ${BOOST_LIBRARIES} + ${OpenCV_LIBS}) diff --git a/comparison/ImageProcessing/CMakeLists.txt b/comparison/ImageProcessing/CMakeLists.txt deleted file mode 100644 index 32a52fb2..00000000 --- a/comparison/ImageProcessing/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -find_package(OpenCV REQUIRED) -include_directories(${OpenCV_INCLUDE_DIRS}) - -add_executable(boost_gil_conv2d boost_gil_conv2d.cpp) -find_package(Boost) -if(Boost_FOUND) - message(STATUS "boost include path is : ${Boost_INCLUDE_DIRS}") - include_directories(${Boost_INCLUDE_DIRS}) -else() - message(WARNING "boost not found.") -endif() -find_package(PNG REQUIRED) -target_link_libraries(boost_gil_conv2d - PNG::PNG - ${BOOST_LIBRARIES} - ${OpenCV_LIBS}) diff --git a/comparison/README.md b/comparison/README.md new file mode 100644 index 00000000..5c78f53b --- /dev/null +++ b/comparison/README.md @@ -0,0 +1,70 @@ +# Convolution Comparison + +## Generate comparison build files + +``` +$ cd buddy-benchmark +$ mkdir build && cd build +$ cmake -G Ninja .. \ + -DBUILD_COMPARISONS=ON +``` + +## Instructions for installing dependencies for comparison examples. + + - Create and activate a separate virtual environment + +``` +sudo apt install python3.8-venv +python3 -m venv /path/to/new/virtual/environment +source /path/to/new/virtual/environment/bin/activate +``` + + - Install dependencies + +``` +pip install tensorflow +pip install opencv-python +pip install torch +pip install onnx +pip install onnxruntime +``` + +> **_NOTE:_** In order to run boost_gil_conv2d.cpp, one has to install the Boost distribution and +> its related dependencies. Instructions regarding Boost installation can be found here : https://www.boost.org/doc/libs/1_77_0/more/getting_started/unix-variants.html +> More information regarding external dependencies can be found here : https://github.com/boostorg/gil/blob/develop/CONTRIBUTING.md#install-dependencies + +## Run Comparison + +Please make sure TensorFlow, PyTorch, onnx, onnxruntime are installed in your environment. + +- TensorFlow + +``` +$ cd buddy-benchmark/comparison/ +$ python3 tf-conv2d.py +``` + +- PyTorch + +``` +$ cd buddy-benchmark/comparison/ +$ python3 pytorch-conv2d.py +``` + +- ONNX Runtime + +``` +$ cd buddy-benchmark/comparison/ +$ python3 gen-conv-models.py +$ python3 onnxruntime-conv2d.py +``` + +- Boost GIL + +``` +$ cd buddy-benchmark/build/ +$ ninja boost_gil_conv2d +$ ./boost_gil_conv2d +``` + +Ex. `./boost_gil_conv2d ../../benchmarks/ImageProcessing/Images/gil_sample.png gil_output.png` diff --git a/comparison/ImageProcessing/boost_gil_conv2d.cpp b/comparison/boost_gil_conv2d.cpp similarity index 100% rename from comparison/ImageProcessing/boost_gil_conv2d.cpp rename to comparison/boost_gil_conv2d.cpp diff --git a/comparison/gen-conv-models.py b/comparison/gen-conv-models.py new file mode 100644 index 00000000..6951f6d7 --- /dev/null +++ b/comparison/gen-conv-models.py @@ -0,0 +1,89 @@ +import onnx +from onnx import numpy_helper +import numpy as np + +# Filter +sobel = { + 3: np.array([[1, 0, -1], + [2, 0, -2], + [1, 0, -1]], dtype='float32'), + 5: np.array([[2, 1, 0, -1, -2], + [3, 2, 0, -2, -3], + [4, 3, 0, -3, -4], + [3, 2, 0, -2, -3], + [2, 1, 0, -1, -2]], dtype='float32'), + 7: np.array([[3, 2, 1, 0, -1, -2, -3], + [4, 3, 2, 0, -2, -3, -4], + [5, 4, 3, 0, -3, -4, -5], + [6, 5, 4, 0, -4, -5, -6], + [5, 4, 3, 0, -3, -4, -5], + [4, 3, 2, 0, -2, -3, -4], + [3, 2, 1, 0, -1, -2, -3]], dtype='float32'), + 9: np.array([[4, 3, 2, 1, 0, -1, -2, -3, -4], + [5, 4, 3, 2, 0, -2, -3, -4, -5], + [6, 5, 4, 3, 0, -3, -4, -5, -6], + [7, 6, 5, 4, 0, -4, -5, -6, -7], + [8, 7, 6, 5, 0, -5, -6, -7, -8], + [7, 6, 5, 4, 0, -4, -5, -6, -7], + [6, 5, 4, 3, 0, -3, -4, -5, -6], + [5, 4, 3, 2, 0, -2, -3, -4, -5], + [4, 3, 2, 1, 0, -1, -2, -3, -4]], dtype='float32') +} + +def get_output_shape(i): + if i == 3: + return [1, 1, 1022, 1022] + elif i == 5: + return [1, 1, 1020, 1020] + elif i == 7: + return [1, 1, 1018, 1018] + elif i == 9: + return [1, 1, 1016, 1016] + +def main(): + for i in range(3, 10, 2): + # Filter + w = sobel[i].reshape((1, 1, i, i)) + + # Input + x = np.random.rand(1, 1, 1024, 1024).astype('float32') + + # Initializer of the weight + initializer_w = numpy_helper.from_array(w, 'w') + + tensor_w = onnx.helper.make_tensor_value_info('w', onnx.TensorProto.FLOAT, [1, 1, i, i]) + tensor_x = onnx.helper.make_tensor_value_info('x', onnx.TensorProto.FLOAT, [1, 1, 1024, 1024]) + tensor_y = onnx.helper.make_tensor_value_info('y', onnx.TensorProto.FLOAT, get_output_shape(i)) + + # Create a node + node_def = onnx.helper.make_node( + 'Conv', + inputs=['x', 'w'], + outputs=['y'], + kernel_shape=[i, i] + ) + + # Create the graph + graph_def = onnx.helper.make_graph( + [node_def], + f'conv_{i}x{i}', + [tensor_x], + [tensor_y], + [initializer_w] + ) + + # Create the model + model_def = onnx.helper.make_model(graph_def, + producer_name='python_script', + ir_version=6 + ) + model_def.opset_import[0].version = 10 + + # Check the model + onnx.checker.check_model(model_def) + + # Save the model + onnx.save(model_def, f'conv_{i}x{i}.onnx') + +if __name__ == "__main__": + main() diff --git a/comparison/onnxruntime-conv2d.py b/comparison/onnxruntime-conv2d.py new file mode 100644 index 00000000..c9c5248d --- /dev/null +++ b/comparison/onnxruntime-conv2d.py @@ -0,0 +1,33 @@ +import numpy as np +import cv2 +import onnxruntime +import time + +def test_conv2d(img, filter_size): + start = time.time() + # Load the model + model_path = f'conv_{filter_size}x{filter_size}.onnx' + ort_session = onnxruntime.InferenceSession(model_path) + # Run inference + ort_inputs = {ort_session.get_inputs()[0].name: img} + ort_outs = ort_session.run(None, ort_inputs) + edge_detect = ort_outs[0] + edge_detect = edge_detect.squeeze() + end = time.time() + print(f'conv {filter_size}x{filter_size} : {end - start}') + return edge_detect + +def main(): + img = cv2.imread('../benchmarks/ImageProcessing/Images/YuTu1024.png',cv2.IMREAD_GRAYSCALE) + # Convert the image to numpy array. + img = np.array(img, dtype='float32') + img = img.reshape((1, 1, img.shape[0], img.shape[1])) + ''' + Perform the edget detection. + ''' + for i in range(3, 10, 2): + edge_detect = test_conv2d(img, i) + cv2.imwrite(f'./onnxruntime-conv2d_{i}.png', edge_detect) + +if __name__ == "__main__": + main() diff --git a/comparison/pytorch-conv2d.py b/comparison/pytorch-conv2d.py new file mode 100644 index 00000000..8208c08b --- /dev/null +++ b/comparison/pytorch-conv2d.py @@ -0,0 +1,68 @@ +import torch +import numpy as np +import cv2 +import time +from torch.autograd import Variable +import torch.nn.functional as F + +sobel_3x3 = np.array([[1, 0, -1], + [2, 0, -2], + [1, 0, -1]], dtype='float32') + +sobel_5x5 = np.array([[2, 1, 0, -1, -2], + [3, 2, 0, -2, -3], + [4, 3, 0, -3, -4], + [3, 2, 0, -2, -3], + [2, 1, 0, -1, -2]], dtype='float32') + +sobel_7x7 = np.array([[3, 2, 1, 0, -1, -2, -3], + [4, 3, 2, 0, -2, -3, -4], + [5, 4, 3, 0, -3, -4, -5], + [6, 5, 4, 0, -4, -5, -6], + [5, 4, 3, 0, -3, -4, -5], + [4, 3, 2, 0, -2, -3, -4], + [3, 2, 1, 0, -1, -2, -3]], dtype='float32') + +sobel_9x9 = np.array([[4, 3, 2, 1, 0, -1, -2, -3, -4], + [5, 4, 3, 2, 0, -2, -3, -4, -5], + [6, 5, 4, 3, 0, -3, -4, -5, -6], + [7, 6, 5, 4, 0, -4, -5, -6, -7], + [8, 7, 6, 5, 0, -5, -6, -7, -8], + [7, 6, 5, 4, 0, -4, -5, -6, -7], + [6, 5, 4, 3, 0, -3, -4, -5, -6], + [5, 4, 3, 2, 0, -2, -3, -4, -5], + [4, 3, 2, 1, 0, -1, -2, -3, -4]], dtype='float32') + +sobel_3x3_filter = sobel_3x3.reshape((1, 1, 3, 3)) +sobel_5x5_filter = sobel_5x5.reshape((1, 1, 5, 5)) +sobel_7x7_filter = sobel_7x7.reshape((1, 1, 7, 7)) +sobel_9x9_filter = sobel_9x9.reshape((1, 1, 9, 9)) + +def test_conv2d(img, kernel): + weight = Variable(torch.from_numpy(kernel)) + start = time.time() + edge_detect = F.conv2d(Variable(img), weight) + end = time.time() + print(end - start) + edge_detect = edge_detect.squeeze().detach().numpy() + return edge_detect + +def main(): + img = cv2.imread('../benchmarks/ImageProcessing/Images/YuTu1024.png',cv2.IMREAD_GRAYSCALE) + # Convert the image to numpy array. + img = np.array(img, dtype='float32') + # Convert the numpy array to torch tensor. + img = torch.from_numpy(img.reshape((1, 1, img.shape[0], img.shape[1]))) + ''' + Perform the edget detection. + Uncomment to use the corresponding size kernel for testing. + Note that only one kernel size is used for testing at a time. + ''' + edge_detect = test_conv2d(img, sobel_3x3_filter) + # edge_detect = test_conv2d(img, sobel_5x5_filter) + # edge_detect = test_conv2d(img, sobel_7x7_filter) + # edge_detect = test_conv2d(img, sobel_9x9_filter) + cv2.imwrite("./pytorch-conv2d.png", edge_detect) + +if __name__ == "__main__": + main() diff --git a/comparison/tf-conv2d.py b/comparison/tf-conv2d.py new file mode 100644 index 00000000..7706a478 --- /dev/null +++ b/comparison/tf-conv2d.py @@ -0,0 +1,62 @@ +import tensorflow as tf +import numpy as np +import cv2 +import time + +sobel_3x3 = tf.constant([[-1, 0, 1], + [-2, 0, 2], + [-1, 0, 1]], dtype='float32') + +sobel_5x5 = tf.constant([[2, 1, 0, -1, -2], + [3, 2, 0, -2, -3], + [4, 3, 0, -3, -4], + [3, 2, 0, -2, -3], + [2, 1, 0, -1, -2]], dtype='float32') + +sobel_7x7 = tf.constant([[3, 2, 1, 0, -1, -2, -3], + [4, 3, 2, 0, -2, -3, -4], + [5, 4, 3, 0, -3, -4, -5], + [6, 5, 4, 0, -4, -5, -6], + [5, 4, 3, 0, -3, -4, -5], + [4, 3, 2, 0, -2, -3, -4], + [3, 2, 1, 0, -1, -2, -3]], dtype='float32') + +sobel_9x9 = tf.constant([[4, 3, 2, 1, 0, -1, -2, -3, -4], + [5, 4, 3, 2, 0, -2, -3, -4, -5], + [6, 5, 4, 3, 0, -3, -4, -5, -6], + [7, 6, 5, 4, 0, -4, -5, -6, -7], + [8, 7, 6, 5, 0, -5, -6, -7, -8], + [7, 6, 5, 4, 0, -4, -5, -6, -7], + [6, 5, 4, 3, 0, -3, -4, -5, -6], + [5, 4, 3, 2, 0, -2, -3, -4, -5], + [4, 3, 2, 1, 0, -1, -2, -3, -4]], dtype='float32') + +sobel_3x3_filter = tf.reshape(sobel_3x3, [3, 3, 1, 1]) +sobel_5x5_filter = tf.reshape(sobel_5x5, [5, 5, 1, 1]) +sobel_7x7_filter = tf.reshape(sobel_7x7, [7, 7, 1, 1]) +sobel_9x9_filter = tf.reshape(sobel_9x9, [9, 9, 1, 1]) + +def test_conv2d(img, kernel): + start = time.time() + output = tf.nn.conv2d(img, kernel, strides=[1, 1, 1, 1], padding='VALID') + end = time.time() + print(end - start) + output_array = np.asarray(output) + cv2.imwrite("./tf-conv2d.png", output_array[0,:,:,0]) + +def main(): + img = cv2.imread('../benchmarks/ImageProcessing/Images/YuTu1024.png',cv2.IMREAD_GRAYSCALE) + img = tf.constant(img, tf.float32) + img = tf.reshape(img, [1, img.shape[0], img.shape[1], 1]) + ''' + Perform the edget detection. + Uncomment to use the corresponding size kernel for testing. + Note that only one kernel size is used for testing at a time. + ''' + test_conv2d(img, sobel_3x3_filter) + # test_conv2d(img, sobel_5x5_filter) + # test_conv2d(img, sobel_7x7_filter) + # test_conv2d(img, sobel_9x9_filter) + +if __name__ == "__main__": + main() From 6cb52f356209a579ba4ff934f71a243787861bc3 Mon Sep 17 00:00:00 2001 From: meshtag Date: Tue, 26 Apr 2022 22:55:40 +0800 Subject: [PATCH 4/4] Trivial improvement in installation instructions --- comparison/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/comparison/README.md b/comparison/README.md index 5c78f53b..0730f844 100644 --- a/comparison/README.md +++ b/comparison/README.md @@ -35,7 +35,7 @@ pip install onnxruntime ## Run Comparison -Please make sure TensorFlow, PyTorch, onnx, onnxruntime are installed in your environment. +Please make sure TensorFlow, OpenCV, PyTorch, ONNX, ONNX Runtime are installed in your environment. - TensorFlow