우선 1부에서 아두이노와 웹서버의 연결을 완료했으니
이제 visual studio에서 웹서버로 정보를 전송하면 완료된다.
우선 필요한것은 와이파이 연결되는 컴퓨터와 웹캠이다.
그리고 라이브러리는 opencv와 curl이 필요하다.
opencv에 관한 설치방법은 인터넷에 많기 때문에 생략하고
인터넷 통신을 가능하게 하는 curl라이브러리는 다음 글을 확인하길 바란다.
https://jiwoojung.tistory.com/1
CURL 라이브러리 Visual Studio 연동
우선 필자는 visual studio 2022 버전을 사용한다. 1.[다운로드]https://curl.se/download/ curl downloads curl.se위 사이트를 통해 최신 버전을 다운받는다.+) 2024.07.13 기준으로 최신버전이 8.8.0 버전이다. 하지만
jiwoojung.tistory.com
C++ 코드를 보여주자면 다음과 같다.
+) 49줄에 std::string arduinoIP = "ip"; // 아두이노의 IP 주소
부분에 ip대신 1부에서 설명한듯이 실행하여 나오는 와이파이의 ip 주소를 입력하여야 한다.
#include <opencv2/opencv.hpp>
#include <iostream>
#include <string>
#include <curl/curl.h>
#include <Windows.h>
#include <thread>
using namespace cv;
using namespace std;
#define CURL_STATICLIB
#pragma comment(lib, "libcurld.lib")
#pragma comment(lib, "wldap32.lib")
#pragma comment(lib, "ws2_32.lib")
void sendDataToArduino(const std::string& ip, const std::string& command) {
CURL* curl;
CURLcode res;
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if (curl) {
std::string url = "http://" + ip + "/" + command;
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
}
curl_easy_cleanup(curl);
}
curl_global_cleanup();
}
void sendDataToArduinoAsync(const std::string& ip, const std::string& command) {
std::thread([ip, command]() {
sendDataToArduino(ip, command);
}).detach();
}
int main() {
VideoCapture cap(0); // 첫 번째 카메라 사용
if (!cap.isOpened()) {
cout << "Error: Could not open the camera." << endl;
return -1;
}
std::string arduinoIP = "ip"; // 아두이노의 IP 주소
Mat frame, hsv, mask;
int frame_width = cap.get(CAP_PROP_FRAME_WIDTH);
int frame_height = cap.get(CAP_PROP_FRAME_HEIGHT);
while (true) {
cap >> frame;
if (frame.empty()) {
cout << "Error: Could not capture frame." << endl;
break;
}
cvtColor(frame, hsv, COLOR_BGR2HSV);
Scalar lower_blue(100, 150, 50);
Scalar upper_blue(140, 255, 255);
inRange(hsv, lower_blue, upper_blue, mask);
vector<vector<Point>> contours;
findContours(mask, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
Point2f center;
float radius;
float max_area = 0;
Point2f max_center;
float max_radius;
for (size_t i = 0; i < contours.size(); i++) {
float area = contourArea(contours[i]);
if (area < 300) {
continue;
}
if (area > max_area) {
max_area = area;
minEnclosingCircle(contours[i], max_center, max_radius);
}
}
if (max_area > 0) {
circle(frame, max_center, (int)max_radius, Scalar(0, 255, 0), 2);
circle(frame, max_center, 5, Scalar(0, 0, 255), -1);
int posx = (max_center.x / frame_width) * 180;
int posy = (max_center.y / frame_height) * 180;
std::string command = "X" + std::to_string(posx) + "Y" + std::to_string(posy);
sendDataToArduinoAsync(arduinoIP, command);
}
imshow("Frame", frame);
imshow("Mask", mask);
if (waitKey(30) >= 0) break;
}
return 0;
}
필자는 우선 파란색의 물체를 검출하여 좌표값을 반환하고
이를 180도 기준으로 분할하여 X,Y축으로 이동해야 하는각도를 서버에 보내는 작업을 코드로 작성하였다.
1부에서 완성한 아두이노를 실행하여 웹서버를 개설하고, 이후 visual studio를 실행하여 정보를 보내면 완성이다.
데모결과는 아래영상과 같은 모습이다.
https://youtu.be/f2TUxoaKIsA?si=X2wu3TiXFxsy7mnI
위 영상은 파이썬으로 작동시킨 모습이고 블로그의 코드는 C++을 활용하여 작동시킨 코드이다.
추가적인 오류나 문의사항은 댓글로 알려주시면 됩니다.
'C,C++' 카테고리의 다른 글
[백준 C++]2869번 문제 - 달팽이는 올라가고 싶다(설명 포함) (2) | 2024.11.18 |
---|---|
CURL 라이브러리 Visual Studio 연동 (0) | 2024.07.13 |