根据官方博客进行测试ACL:Cartoonifying Images on Raspberry Pi with the Compute Library
我的情况是:我借助matlab实现与树莓派的远程连接,matlab的作用主要是传输文件用的和远程连接。
1、我是在树莓派上进行编译的
官方代码是:
# Install dependencies (g++, git and scons)
sudo apt-get install g++ git scons
# Clone Compute Library
git clone https://github.com/Arm-software/ComputeLibrary.git
# Enter ComputeLibrary folder
cd ComputeLibrary
# Build the library and the examples
scons Werror=1 debug=0 asserts=0 neon=1 opencl=0 examples=1 build=native -j2
我是直接在电脑上载好的,然后传给树莓派,直接下太慢了
用:putFile(mypi,'C:/Users/NEVERGUVEIP/ComputeLibrary-#master.zip','/home/pi/') 进行文件的传输,然后进行解压
当我进行第一次编译时,应该是没有问题的,但是当我安装第二个ACL库,经行第二次编译时,系统报错,说是没有target “-j2”.
(我直接运行scons,后面的一堆参数都没用,我感觉只删除‘-j2’应该就行了,因为直接scons的话,编译时间太长了。还有这个-j2我现在都不知道啥意思。)
2、进行测试时
LD_LIBRARY_PATH=build/ ./build/examples/neon_convolution
我从git上直接下载的ACL版本应该时最新版的吧,这时的neon_convolution不在build下,而是在examples文件夹下,这样测试时就能通过了。直接运行官方代码会报错。说找不到文件。
3、运行实例时
我把他们的代码直接复制到树莓派,新建一个test.cpp文件. 然后用g++编译。
home/pi/ComputeLibrary下面放的就是ACM的相关文件
一开始用g++ test.cpp,报错,说找不到头文件。
3.1 编译报错(1)
arm_compute/runtime/NEON/NEFunctions.h:28:69: fatal error:
arm_compute/runtime/NEON/functions/NEAbsoluteDifference.h:No such file or directory
#include "arm_compute/runtime/NEON/functions/NEAbsoluteDifference.h"
解决方法:编译时要添加路径:就是-I后面的路径,不然总是报错,找不到头文件。
g++ -I/home/pi/ComputeLibrary test.cpp
3.2 编译报错(2)
/home/pi/ComputeLibrary/support/Half.h:36:25: fatal error: half/half.hpp: No such file or directory
#include "half/half.hpp"
解决办法:
这是因为half.cpp文件已经不在half文件下了,用sudo find -name half.hpp可以发现这个文件在include文件夹下,所以修改
/home/pi/ComputeLibrary/support/Half.h文件中#include "half/half.hpp"为:#include "include/half/half.hpp"
3.3 继续编译报错(3)
utils/Utils.h:33:26: fatal error: libnpy/npy.hpp: No such file or directory
#include "libnpy/npy.hpp"
这个和上个错误一样,打开utils/Utils.h文件,修改为 #include "include/libnpy/npy.hpp"
3.4 编译继续报错
test.cpp:24:5: error: ‘PPMLoader’ was not declared in this scope
PPMLoader ppm;
^~~~~~~~~
test.cpp:25:5: error: ‘ppm’ was not declared in this scope
ppm.open(argv[1]);
心里mmp呀,这TM还能让人好好玩耍吗。
解决办法:PPMLoader是在:#include "utils/ImageLoader.h"头文件下。把这个代码加到头文件中
3.5 还报错,我已经到崩坏的边缘了,别惹我
In file included from test.cpp:4:0:
utils/ImageLoader.h:36:27: fatal error: stb/stb_image.h: No such file or directory
#include "stb/stb_image.h"
解决方法:和前俩个错误一样,修改ImageLoader.h的文件的中“ #include "stb/stb_image.h"”,为 #include "include/stb/stb_image.h"
。。。。。。。。。。。。。。。。
3.6 理论上经过修改的代码是没有问题了,可是进行g++编译时,还是报错,这次的错,呵呵,感觉解决不了,或者说这就不应该这样编译。因为我使用g++对系统自带的源码进行编译时,报了同样的错。
/tmp/ccvZEwyw.o: In function `arm_compute::TensorInfo::~TensorInfo()':
neon_cartoon_effect.cpp:(.text._ZN11arm_compute10TensorInfoD2Ev[_ZN11arm_compute10TensorInfoD5Ev]+0x38): undefined reference to `vtable for arm_compute::TensorInfo'
collect2: error: ld returned 1 exit status
/
在解决bug的途中,直到我发现了真相
4、总结(真相)
4.1真相
其实这个例子是包含在ACL中的,在examples 下找到neon_cartoon_effect.cpp 。
在ACM18.11版本中的源码为:这个源码和官方博客中的代码有不点区别了的。我们进行scons时,已经进行编译过了的。
#include "arm_compute/runtime/NEON/NEFunctions.h"
#include "arm_compute/core/Types.h"
#include "utils/ImageLoader.h"
#include "utils/Utils.h"
using namespace arm_compute;
using namespace utils;
class NEONCartoonEffectExample : public Example
{
public:
bool do_setup(int argc, char **argv) override
{
// Open PPM file
PPMLoader ppm;
if(argc < 2)
{
// Print help
std::cout << "Usage: ./build/neon_cartoon_effect [input_image.ppm]\n\n";
std::cout << "No input_image provided, creating a dummy 640x480 image\n";
// Create an empty grayscale 640x480 image
src_img.allocator()->init(TensorInfo(640, 480, Format::U8));
}
else
{
ppm.open(argv[1]);
ppm.init_image(src_img, Format::U8);
}
// Initialize just the dimensions and format of the images:
gaus5x5_img.allocator()->init(*src_img.info());
canny_edge_img.allocator()->init(*src_img.info());
dst_img.allocator()->init(*src_img.info());
// Configure the functions to call
gaus5x5.configure(&src_img, &gaus5x5_img, BorderMode::REPLICATE);
canny_edge.configure(&src_img, &canny_edge_img, 100, 80, 3, 1, BorderMode::REPLICATE);
sub.configure(&gaus5x5_img, &canny_edge_img, &dst_img, ConvertPolicy::SATURATE);
// Now that the padding requirements are known we can allocate the images:
src_img.allocator()->allocate();
dst_img.allocator()->allocate();
gaus5x5_img.allocator()->allocate();
canny_edge_img.allocator()->allocate();
// Fill the input image with the content of the PPM image if a filename was provided:
if(ppm.is_open())
{
ppm.fill_image(src_img);
output_filename = std::string(argv[1]) + "_out.ppm";
}
return true;
}
void do_run() override
{
// Execute the functions:
gaus5x5.run();
canny_edge.run();
sub.run();
}
void do_teardown() override
{
// Save the result to file:
if(!output_filename.empty())
{
save_to_ppm(dst_img, output_filename); // save_to_ppm maps and unmaps the image to store as PPM
}
}
private:
Image src_img{}, dst_img{}, gaus5x5_img{}, canny_edge_img{};
NEGaussian5x5 gaus5x5{};
NECannyEdge canny_edge{};
NEArithmeticSubtraction sub{};
std::string output_filename{};
};
/** Main program for cartoon effect test
*
* @param[in] argc Number of arguments
* @param[in] argv Arguments ( [optional] Path to PPM image to process )
*/
int main(int argc, char **argv)
{
return utils::run_example<NEONCartoonEffectExample>(argc, argv);
}
4.2 测试图片
LD_LIBRARY_PATH=build/ ./build/examples/neon_cartoon_effect school_bus.ppm
4.2 测试效果图
左边是原图,右边是效果图。老子老吃饭去了/ 一个来自对c++不懂人的呐喊