0


【Opencv】在Visual Studio 2022和UE5上配置OpenCV的详细步骤

一、下载并安装OpenCV
访问OpenCV官网:首先,你需要访问OpenCV的官方网站(OpenCV官网),在“Releases”部分找到适合你的操作系统的版本进行下载。对于Windows用户,通常会选择Windows预编译的二进制文件。
下载并安装:下载适合你系统的OpenCV版本后,按照安装向导进行安装。注意选择一个不包含中文和特殊字符的路径,以避免潜在的问题。
二、配置系统环境变量
打开系统属性:在Windows搜索栏中输入“系统属性”,然后选择“打开”以进入系统属性界面。
编辑环境变量:点击“高级”选项卡下的“环境变量”按钮。在“系统变量”区域找到名为“Path”的变量,选择它并点击“编辑”。
添加OpenCV路径:点击“新建”并添加OpenCV的bin目录路径到你的Path变量中。这个路径通常类似于C:\opencv\build\x64\vc16\bin(注意替换为你的实际安装路径)。
保存并重启:点击“确定”保存更改,并重启你的计算机以确保环境变量生效。
三、在Visual Studio中配置项目属性
创建或打开项目:在Visual Studio 2022中创建一个新的C++项目或打开一个现有的项目。
配置项目属性:
右键点击项目名称,选择“属性”。
在左侧导航栏中,选择“VC++目录”。
在“包含目录”中添加OpenCV的include目录路径,如C:\opencv\build\include和C:\opencv\build\include\opencv2。
在“库目录”中添加OpenCV的lib目录路径,如C:\opencv\build\x64\vc16\lib(注意根据你的Visual Studio版本和OpenCV构建配置选择正确的目录)。
配置链接器:
在项目属性中,选择“链接器”->“输入”。
在“附加依赖项”中添加你需要的OpenCV库文件,如opencv_worldXXXd.lib(XXX是版本号,d表示debug版本,对于release版本则不需要d)。注意,如果你没有使用opencv_world这样的统一库,而是分别链接了不同的模块,那么你需要添加相应模块的库文件。
四、编写和测试代码
编写代码:在你的C++项目中编写使用OpenCV的代码。例如,一个简单的读取并显示图片的代码示例如下:

#include<opencv2/opencv.hpp>usingnamespace cv;intmain(){  
    Mat img =imread("G:\\111111111111111111111111111\\213213.jpg");// 替换为你的图片路径  if(img.empty()){  
        std::cerr <<"Error: Loading image"<< std::endl;return-1;}imshow("Image Display", img);waitKey(0);return0;}

编译并运行:编译你的项目并运行它。如果一切配置正确,你应该能够看到你的图片在一个窗口中显示。
注意
确保你的OpenCV版本与你的Visual Studio版本兼容。
如果你在配置过程中遇到任何问题,检查你的路径设置是否正确,特别是环境变量和项目属性中的路径。
如果你使用的是预编译的OpenCV库,确保它们是为你的Visual Studio版本和Windows SDK版本构建的。如果不是,你可能需要从源代码自行编译OpenCV。

2cv::imshow(“Original Image”, img); 严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息 错误 LNK2019 无法解析的外部符号 “void __cdecl cv::imshow(class std::basic_string<char,struct std::char_traits,class std::allocator > const &,class cv::debug_build_guard::_InputArray const &)” (?imshow@cv@@YAXAEBV?

     b 
    
   
     a 
    
   
     s 
    
   
     i 
    
    
    
      c 
     
    
      s 
     
    
   
     t 
    
   
     r 
    
   
     i 
    
   
     n 
    
   
     g 
    
   
     @ 
    
   
     D 
    
   
     U 
    
   
     ? 
    
   
  
    basic_string@DU? 
   
  
basics​tring@DU?char_traits@D@std@@V?$allocator@D@2@@std@@AEBV_InputArray@debug_build_guard@1@@Z),函数 main 中引用了该符号 opencv1 G:\VS2022_programs\Opencv_0726_VS2022\opencv1\opencv1\opencv1.obj 1

答:错误 LNK2019 表示链接器无法找到在代码中引用的某个函数或符号的实现。在你的情况下,链接器无法找到 cv::imshow 函数的实现,这通常是因为OpenCV库没有被正确地链接到你的项目中。

这里有几个步骤可以帮助你解决这个问题:

确认OpenCV库文件已被添加到项目中:
确保你已经将OpenCV的库文件(.lib 文件)添加到了项目的链接器输入中。这通常在项目的属性设置中的“链接器”->“输入”->“附加依赖项”中完成。
检查库文件的路径:
在项目的属性中,确保“VC++目录”->“库目录”中包含了OpenCV库文件的路径。这样,链接器就能在这些目录中查找库文件。
确认使用的是正确的库文件:
如果你使用的是OpenCV的Debug版本,那么你需要链接到带有d后缀的库文件(例如opencv_world451d.lib),而对于Release版本,则应该链接不带d后缀的库文件(例如opencv_world451.lib)。
检查项目配置:
确保你的项目配置(Debug或Release)与你链接的库文件配置相匹配。
重新生成项目:
在Visual Studio中,尝试清理并重新生成你的项目。这可以通过“生成”菜单中的“清理解决方案”和“重新生成解决方案”来完成。
检查OpenCV的安装:
如果以上步骤都不能解决问题,可能需要检查你的OpenCV安装是否完整或是否有损坏。你可以尝试重新安装OpenCV,或者从其他来源获取库文件。
检查Visual Studio的版本和更新:
确保你的Visual Studio和所有相关的组件都已更新到最新版本。
检查项目设置中的字符集:
在某些情况下,如果你的项目设置为使用多字节字符集(MBCS),而OpenCV库是使用Unicode字符集编译的,这也可能导致链接问题。尝试将项目的字符集设置为“使用Unicode字符集”。
如果以上步骤仍然无法解决问题,你可能需要查看更详细的错误信息或日志,以获取更多关于为什么链接器无法找到 cv::imshow 的线索。此外,确保你的OpenCV版本与你的Visual Studio版本兼容。如果你使用的是较新版本的Visual Studio,可能需要从源代码编译OpenCV或使用预编译的二进制文件,这些二进制文件是为较新版本的Visual Studio编译的。
如果是UE5进行配置,那么除了上面的步骤(除去链接库更改外,还需要更改.Build.cs文件),如下:

// Copyright Epic Games, Inc. All Rights Reserved.

using System.IO;
using UnrealBuildTool;

public class Ceshi_0726 : ModuleRules
{
    public Ceshi_0726(ReadOnlyTargetRules Target) : base(Target)
    {
        PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
    
        PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });
        // 假设你的静态库头文件在 Source/ThirdParty/MyLib/Include 下  
        // 静态库文件在 Source/ThirdParty/MyLib/Lib 目录下(假设为Windows平台)  
        string ThirdPartyPath = Path.GetFullPath(Path.Combine(ModuleDirectory, "..", "ThirdParty"));
        string LibIncludePath = Path.Combine(ThirdPartyPath, "MyLib", "Include");
        string LibPath = Path.Combine(ThirdPartyPath, "MyLib", "Lib", Target.Platform.ToString());
        // 添加包含目录  
        PublicIncludePaths.AddRange(new string[] { LibIncludePath });
        PublicIncludePaths.AddRange(new string[] { LibIncludePath ,"opencv2"});
        PublicIncludePaths.AddRange(new string[] { LibIncludePath, "opencv2" ,"core"});
        PublicIncludePaths.AddRange(new string[] { LibIncludePath, "opencv2", "core" , "cuda" });
        // 静态库文件,注意这里假设库文件名为 MyLib.lib(Windows平台)  
        // 对于其他平台,如Linux或Mac,你可能需要调整文件名和路径  
        if (Target.Platform == UnrealTargetPlatform.Win64)
        {
            PublicAdditionalLibraries.Add(Path.Combine(LibPath, "StaticLib1.lib"));
           // PublicAdditionalLibraries.Add(Path.Combine(LibPath, "opencv1.lib"));
            PublicAdditionalLibraries.Add(Path.Combine(LibPath, "opencv_world4100d.lib"));
           // PublicAdditionalLibraries.Add(Path.Combine(LibPath, "opencv_world4100d.lib"));
        }

        // 如果有多个静态库或不同平台的库,可以按上述方式继续添加  

        // Uncomment if you are using Slate UI  
        // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });  

        // Uncomment if you are using online features  
        // PrivateDependencyModuleNames.Add("OnlineSubsystem");  

        // 注意:对于动态链接库(DLLs),你可能需要使用PublicLibraryPaths和PublicDelayLoadDLLs  

        PrivateDependencyModuleNames.AddRange(new string[] {  });

        // Uncomment if you are using Slate UI
        // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
        
        // Uncomment if you are using online features
        // PrivateDependencyModuleNames.Add("OnlineSubsystem");

        // To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
    }
}

但是由于opencv的代码需要一个while(1),所以放到UE里并不适用,不如在外部将opencv项目写成一个udp服务器,把UE项目写成udp客户端。

下面的代码是udp传输面部位置的代码:

#include<opencv2/opencv.hpp>#include<iostream>#include<memory>#include<winsock2.h>#include<string>#include<thread>// 用于多线程  #include<chrono>// 用于时间操作  #include<mutex>#include<ws2tcpip.h>
std::mutex mtx;// 用于保护 abcd 和 pShared#pragmacomment(lib,"ws2_32.lib")// 链接Winsock库  #definePORT7509#defineBUFSIZE1024#defineSEND_INTERVAL1000// 发送间隔时间,单位毫秒  
WSADATA wsaData;
SOCKET sock;structsockaddr_in serverAddr, clientAddr, clientAddr2;int bytesReceived;char buffer[BUFSIZE];int addrLen;classEMA{private:double alpha;double previous;public:EMA(double a):alpha(a),previous(0.0){}doubleupdate(double newValue){double ema = alpha * newValue +(1- alpha)* previous;
        previous = ema;return ema;}};voidsendMessageContinuously(SOCKET sock, sockaddr_in clientAddr, std::shared_ptr<std::string> pShared){
    sockaddr_in destAddr;memset(&destAddr,0,sizeof(destAddr));// 初始化结构体  
    destAddr.sin_family = AF_INET;
    destAddr.sin_port =htons(7503);// 假设你希望发送到这个端口  // 使用inet_pton将IP地址字符串转换为二进制形式  if(inet_pton(AF_INET,"127.0.0.1",&destAddr.sin_addr)<=0){// 处理错误  //  std::cerr << "Invalid address/Address not supported\n";return;}while(true){
        
        addrLen =sizeof(clientAddr);//sendto(sock, pShared->c_str(), pShared->length(), 0, (struct sockaddr*)&clientAddr, addrLen);//这个要加上接收哪个才有用//sendto(sock, pShared->c_str(), pShared->length(), 0, (struct sockaddr*)&clientAddr, sizeof(clientAddr));//这个不用收,但是地址是0.0.0.0sendto(sock, pShared->c_str(), pShared->length(),0,(structsockaddr*)&destAddr,sizeof(destAddr));//  std::cout << "Continuous message sent.:::"<< pShared->c_str() <<std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(100));}}intmain(){

    EMA xEMA(0.1);// 假设alpha为0.1  
    EMA yEMA(0.1);// 初始化摄像头  
    cv::VideoCapture capture(0);// 检查摄像头是否成功打开  if(!capture.isOpened()){
        std::cerr <<"Error: Unable to open camera\n";return-1;}// 加载人脸检测的Haar级联分类器  
    cv::CascadeClassifier face_cascade;//   if (!face_cascade.load("E:\\Program Files\\Opencv\\opencv\\build\\etc\\haarcascades\\haarcascade_frontalface_default.xml")) {if(!face_cascade.load("E:\\Program Files\\Opencv\\opencv\\sources\\data\\haarcascades_cuda\\haarcascade_frontalface_default.xml")){
        std::cerr <<"Error: Unable to load face cascade classifier\n";return-1;}// 创建一个窗口  
    cv::namedWindow("Camera Feed with Faces", cv::WINDOW_AUTOSIZE);
    cv::Mat frame, gray;// 初始化Winsock  if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0){
        std::cerr <<"Winsock初始化失败,错误代码: "<<WSAGetLastError()<< std::endl;return1;}// 创建UDP socket  if((sock =socket(AF_INET, SOCK_DGRAM,0))== INVALID_SOCKET){
        std::cerr <<"创建socket失败,错误代码: "<<WSAGetLastError()<< std::endl;WSACleanup();return1;}
    std::cout <<"Socket创建成功。\n";// 设置服务器地址结构  
    clientAddr.sin_family = AF_INET;
    clientAddr.sin_addr.s_addr = INADDR_ANY;
    clientAddr.sin_port =htons(7503);// 设置服务器地址结构  
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = INADDR_ANY;
    serverAddr.sin_port =htons(7500);// 绑定socket  if(bind(sock,(structsockaddr*)&serverAddr,sizeof(serverAddr))== SOCKET_ERROR){
        std::cerr <<"绑定失败,错误代码: "<<WSAGetLastError()<< std::endl;closesocket(sock);WSACleanup();return1;}

    std::cout <<"绑定成功。\n";constchar* p;//std::shared_ptr<std::string> pShared = std::make_shared<std::string>("p$x:12.234632$y:54.812842$z:60.3453\n");
    std::shared_ptr<std::string> pShared = std::make_shared<std::string>("p$x:20$y:54$z:60.3453\n");// 创建并启动发送线程  
    std::thread senderThread(sendMessageContinuously, sock, clientAddr, pShared);int abc =0;// int x, y;double x, y;while(true){// 从摄像头捕获一帧  
        capture >> frame;// 如果帧是空的,跳出循环  if(frame.empty()){
            std::cerr <<"Error: Couldn't receive a frame (stream end?). Exiting ..."<< std::endl;break;}// 转换为灰度图,因为人脸检测通常在灰度图上进行  cvtColor(frame, gray, cv::COLOR_BGR2GRAY);// 检测人脸  
        std::vector<cv::Rect> faces;
        face_cascade.detectMultiScale(gray, faces,2,3,0| cv::CASCADE_SCALE_IMAGE, cv::Size(30,30));// 在原图上绘制矩形框  for(size_t i =0; i < faces.size(); i++){
            cv::rectangle(frame, faces[0], cv::Scalar(255,0,0),2,8,0);//  std::cout << "Face #" << i + 1 << ": Left=" << faces[i].x << ", Top=" << faces[i].y << std::endl;

            std::stringstream ss;

            x = xEMA.update(faces[i].x *(-0.2)+160);
            y = yEMA.update(faces[i].y *(-0.416667)+125);//y = faces[0].y * (-0.416667) + 125;//x = faces[0].x * (-0.2) + 160;/*
          if (faces[i].y * (-0.416667) + 125 - y > 10) { y = y + 10; }
                 else if (faces[i].y * (-0.416667) + 125 - y <  10) { y = y - 10; }
                 if (faces[i].x * (-0.2) + 160 - x> 10) { x = x + 10; }
                 else if (faces[i].x * (-0.2) + 160 - x < 10) { x = x - 10; }
        */if(x >100){ x =100;}if(x <0){ x =0;}if(y >100){ y =100;}if(y <0){ y =0;}
            std::lock_guard<std::mutex>lock(mtx);
            ss <<"p$x:"<< x <<"$y:"<< y <<"$z:20.3453";*pShared = ss.str();}}// 释放摄像头资源  
    capture.release();// 关闭所有OpenCV窗口  
    cv::destroyAllWindows();// 清理  closesocket(sock);WSACleanup();return0;}

本文转载自: https://blog.csdn.net/weixin_48329116/article/details/140798147
版权归原作者 蛋卷卷- 所有, 如有侵权,请联系我们删除。

“【Opencv】在Visual Studio 2022和UE5上配置OpenCV的详细步骤”的评论:

还没有评论