diff --git a/ParkingLot.C b/Actuator/ParkingLot.C similarity index 100% rename from ParkingLot.C rename to Actuator/ParkingLot.C diff --git a/Camera/cam.c b/Camera/cam.c new file mode 100644 index 0000000000000000000000000000000000000000..ada7e9a40272c65b4b0779feb3b164c43af10f1a --- /dev/null +++ b/Camera/cam.c @@ -0,0 +1,163 @@ +#include <sys/stat.h> +#include <sys/types.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <arpa/inet.h> +#include <sys/socket.h> +#include <pthread.h> + +#define BUF_SIZE 1024 + + +int serv_sock, clnt_sock, lcd_sock; +int is_car; + +void error_handling(char *message){ + fputs(message,stderr); + fputc('\n',stderr); + exit(1); +} + +void *wait_client(void* data){ + char* port = (char*)data; + clnt_sock = -1; + struct sockaddr_in serv_addr; + + serv_sock = socket(PF_INET, SOCK_STREAM, 0); + if (serv_sock == -1) + error_handling("socket() error"); + + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); + serv_addr.sin_port = htons(atoi(port)); + + if (bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1) + error_handling("bind() error"); + + int clnt_addr; + socklen_t clnt_addr_size; + + printf("[*] wait for client ...\n"); + + if (listen(serv_sock, 5) == -1) + error_handling("listen() error"); + + if (clnt_sock < 0) { + clnt_addr_size = sizeof(clnt_addr); + clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size); + if (clnt_sock == -1) + error_handling("accept() error"); + else + printf("[*] client connected\n"); + } +} + +void *connect_server(void * data){ + char* addr = ((char**)data)[0]; + char* port = ((char**)data)[1]; + struct sockaddr_in serv_addr; + + lcd_sock = socket(PF_INET, SOCK_STREAM, 0); + if (lcd_sock == -1) + error_handling("socket() error"); + + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = inet_addr(addr); + serv_addr.sin_port = htons(atoi(port)); + + printf("%s %s\n", addr, port); + + if (connect(lcd_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1) + error_handling("connect() error"); + else + printf("server connect \n"); + +} + +void *read_person(){ + char buf[2]; + while(1){ + if(read(clnt_sock, buf, sizeof(buf)) > 0){ + system("raspistill -o /home/uisoo/Desktop/project/Res/input.JPG.jpg"); + system("/home/uisoo/Desktop/opencv"); + FILE* fp; + fp = fopen("/home/uisoo/Desktop/project/output.JPG", "r"); + char *tmp; + fread(tmp, sizeof(char), 1024, fp); + fclose(fp); + printf("%s\n", buf); + if(strcmp(buf, "1") == 0){ + is_car = 1; + write(lcd_sock, tmp, sizeof(tmp)); + }else{ + write(lcd_sock, "empty", sizeof(tmp)); + } + } + } +} + +int main(int argc, char* argv[]) { + + if (argc != 4) { + printf("Usage : %s <sensor port>, <ip> <port> \n", argv[0]); + } + + // Wait Client (Sensor) + pthread_t wait_client_t, connect_lcd_t; + int status; + + if(pthread_create(&wait_client_t, NULL, wait_client, (void*)argv[1]) < 0){ + perror("thread create error: "); + exit(0); + } + + char* serv_info[2] = {argv[2], argv[3]}; + // Connect to LCD + if(pthread_create(&connect_lcd_t, NULL, connect_server, (void*)serv_info) < 0){ + perror("thread create error: "); + exit(0); + } + + pthread_join(wait_client_t, (void **)&status); + pthread_join(connect_lcd_t, (void **)&status); + + + pthread_t read_t; + + if(pthread_create(&read_t, NULL, read_person, NULL) < 0){ + perror("thread create error: "); + exit(0); + } + + while(1){ + sleep(1); + } + + // while(1) + // { + // system("raspistil -o Image.JPG"); + // system(""); + + // if(pthread_create(&file_read_t, NULL, file_read, NULL) < 0){ + // perror("thread create error: "); + // exit(0); + // } + + // pthread_join(file_read_t, (void **)&status); + + // if(pthread_create(&file_exec_t, NULL, file_exec, NULL) < 0){ + // perror("thread create error: "); + // exit(0); + // } + + // pthread_join(file_exec_t, (void **)&status); + // } + + close(serv_sock); + return 0; +} diff --git a/Camera/open.cpp b/Camera/open.cpp new file mode 100644 index 0000000000000000000000000000000000000000..83c35ca9bb4e48437e451e9fa84f684dd330a950 --- /dev/null +++ b/Camera/open.cpp @@ -0,0 +1,300 @@ +#include <vector> +#include <iostream> +#include <leptonica/allheaders.h> +#include <regex> +#include <fstream> +#include <wtypes.h> + +#include <opencv2/highgui.hpp> +#include <opencv2/imgproc.hpp> + +#include <tesseract/baseapi.h> + +using namespace cv; + +DWORD convert_unicode_to_ansi_string(__out std::string& ansi, __in const wchar_t* unicode, __in const size_t unicode_size); +DWORD convert_utf8_to_unicode_string(__out std::wstring& unicode, __in const char* utf8, __in const size_t utf8_size); + +struct myclass { + bool operator() (Rect r1, Rect r2) { return (r1.x < r2.x); } +} myobject; + +std::string utf8_to_string(const char *utf8str) +{ + std::wstring unicode = L""; + std::string ansi = ""; + + convert_utf8_to_unicode_string(unicode, utf8str, std::strlen(utf8str)); + convert_unicode_to_ansi_string(ansi, unicode.c_str(), unicode.size()); + return ansi; +} + +DWORD convert_unicode_to_ansi_string(__out std::string& ansi, __in const wchar_t* unicode, __in const size_t unicode_size) { + + DWORD error = 0; + + do { + + if ((nullptr == unicode) || (0 == unicode_size)) { + error = ERROR_INVALID_PARAMETER; + break; + } + + ansi.clear(); + + // + // getting required cch. + // + + int required_cch = ::WideCharToMultiByte( + CP_ACP, + 0, + unicode, static_cast<int>(unicode_size), + nullptr, 0, + nullptr, nullptr + ); + + if (0 == required_cch) { + error = ::GetLastError(); + break; + } + + // + // allocate. + // + + ansi.resize(required_cch); + + // + // convert. + // + + if (0 == ::WideCharToMultiByte( + CP_ACP, + 0, + unicode, static_cast<int>(unicode_size), + const_cast<char*>(ansi.c_str()), static_cast<int>(ansi.size()), + nullptr, nullptr + )) { + error = ::GetLastError(); + break; + } + + } while (false); + + return error; +} + + +DWORD convert_utf8_to_unicode_string(__out std::wstring& unicode, __in const char* utf8, __in const size_t utf8_size) { + + DWORD error = 0; + + do { + + if ((nullptr == utf8) || (0 == utf8_size)) { + error = ERROR_INVALID_PARAMETER; + break; + } + + unicode.clear(); + + // + // getting required cch. + // + + int required_cch = ::MultiByteToWideChar( + CP_UTF8, + MB_ERR_INVALID_CHARS, + utf8, static_cast<int>(utf8_size), + nullptr, 0 + ); + if (0 == required_cch) { + error = ::GetLastError(); + break; + } + + // + // allocate. + // + + unicode.resize(required_cch); + + // + // convert. + // + + if (0 == ::MultiByteToWideChar( + CP_UTF8, + MB_ERR_INVALID_CHARS, + utf8, static_cast<int>(utf8_size), + const_cast<wchar_t*>(unicode.c_str()), static_cast<int>(unicode.size()) + )) { + error = ::GetLastError(); + break; + } + + } while (false); + + return error; +} + + +std::string getCarNumber(std::string text) { + int i = 0; + + std::regex re("\\d{2,3}\\W{2}\\s{0,}\\d{4}"); + std::smatch match; + if (std::regex_search(text, match, re)) { + return match.str(); + } + else { + return "0"; + } +} + +int main(int argc, const char* argv[]) { + std::vector<std::vector<Point>> contours; + std::vector<Vec4i> hierarchy; + + Mat drawing; + Mat input = imread("/home/uisoo/Desktop/project/Res/input.JPG"); + + Mat image; + + input.copyTo(image); + + cvtColor(image, image, COLOR_RGB2GRAY); + + GaussianBlur(image, image, Size(3, 3), 1, 1, BORDER_DEFAULT); + + Canny(image, image, 100, 300, 3); + + findContours(image, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE); + + + + std::vector<std::vector<Point>> poly(contours.size()); + std::vector<Rect> t(contours.size()); + + std::vector<Rect> bound; + + for (int i = 0; i < contours.size(); i++) { + approxPolyDP(Mat(contours[i]), poly[i], 1, true); + t[i] = boundingRect(Mat(poly[i])); + } + + drawing = Mat::zeros(image.size(), CV_8UC1); + image.copyTo(drawing); + cvtColor(drawing, drawing, COLOR_GRAY2RGB); + + for (int i = 0; i < contours.size(); i++) { + + double ratio = (double)t[i].height / t[i].width; + + if ((ratio <= 2.5) && (ratio >= 0.5) && (t[i].area() <= 700) && (t[i].area() >= 100)) { + + rectangle(drawing, t[i].tl(), t[i].br(), Scalar(0, 255, 0), 0.1, 8, 0); + + bound.push_back(t[i]); + } + } + + sort(bound.begin(), bound.end(), myobject); + + int selectIndex = 0, maxCount = -1; + + for (int i = 0; i < bound.size(); i++) { + int count = 0; + + for (int j = i + 1; j < bound.size(); j++) { + + int delta_x = bound[j].x - bound[i].x; + int delta_y = abs(bound[j].y - bound[i].y); + + if (delta_x > 150) break; + + if (delta_x == 0) delta_x = 1; + if (delta_y == 0) delta_y = 1; + + double gradient = (double)delta_y / delta_x; + + if (gradient < 0.25) + count += 1; + } + + if (count > maxCount) { + selectIndex = i; + maxCount = count; + } + } + + Mat selectContour; + image.copyTo(selectContour); + cvtColor(selectContour, selectContour, COLOR_GRAY2RGB); + + + std::vector<Rect> carNumber; + carNumber.push_back(bound[selectIndex]); + rectangle(selectContour, bound[selectIndex].tl(), bound[selectIndex].br(), Scalar(0, 255, 0), 0.1, 8, 0); + + for (int i = selectIndex + 1; i < bound.size(); i++) { + int delta_x = bound[i].x - bound[selectIndex].x; + int delta_y = abs(bound[i].y - bound[selectIndex].y); + + if (delta_x > 150) break; + + if (delta_x == 0) delta_x = 1; + if (delta_y == 0) delta_y = 1; + + double gradient = (double)delta_y / delta_x; + + if (gradient < 0.25) { + carNumber.push_back(bound[i]); + rectangle(selectContour, bound[i].tl(), bound[i].br(), Scalar(0, 255, 0), 0.05, 8, 0); + } + } + + rectangle(selectContour, carNumber.begin()[0].tl(), carNumber.end()[-1].br(), Scalar(0, 0, 255), 1, 8, 0); + + int offset = 5; + Mat output; + input.copyTo(output); + + output = output(Rect(Point(carNumber.begin()[0].tl().x - offset, carNumber.begin()[0].tl().y - offset), Point(carNumber.end()[-1].br().x + offset, carNumber.end()[-1].br().y + offset))); + imwrite("/home/uisoo/Desktop/project/output.JPG", output); + + tesseract::TessBaseAPI* api = new tesseract::TessBaseAPI(); + api = new tesseract::TessBaseAPI(); + if (api->Init("/home/uisoo/library/tesseract-main", "kor")) { + return -1; + } + + Pix* pix = pixRead("/home/uisoo/Desktop/project/output.JPG"); + + api->SetImage(pix); + api->SetPageSegMode(tesseract::PSM_SINGLE_LINE); // 단일 텍스트 줄 + + std::string recognizedText = api->GetUTF8Text(); + + std::string text = utf8_to_string(recognizedText.c_str()); + text = getCarNumber(text); + // 인식된 번호판 번호 출력 + std::cout << "인식된 번호판 번호: " << text << std::endl; + + std::ofstream file("carNumber"); + if (file.is_open()) { + file << text; + file.close(); // 열었떤 파일을 닫는다. + } + else { + return 1; + } + + // 인식 결과 메모리 해제 + api->End(); + delete api; + pixDestroy(&pix); + + return 0; +}