You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
4.1 KiB
C++
155 lines
4.1 KiB
C++
//
|
|
// Created by UnknownObject on 2022/9/21.
|
|
// Copyright (c) 2022 UnknownNetworkService. All rights reserved.
|
|
//
|
|
|
|
//交通灯识别
|
|
|
|
#include "traffic_light.h"
|
|
|
|
namespace uns
|
|
{
|
|
//取三个数中的最大值
|
|
int TrafficLight::tri_max(int a, int b, int c)
|
|
{
|
|
return std::max(std::max(a, b), c);
|
|
}
|
|
|
|
//根据亮度获取亮起的灯的位置
|
|
cv::Mat TrafficLight::GetLight(const cv::Mat &img)
|
|
{
|
|
cv::Mat hsv;
|
|
cv::cvtColor(img, hsv, cv::COLOR_BGR2HSV);
|
|
cv::Mat chn_v(hsv.size(), CV_8UC1);
|
|
for (int r = 0; r < hsv.rows; r++)
|
|
{
|
|
for (int c = 0; c < hsv.cols; c++)
|
|
{
|
|
uchar v = hsv.at<cv::Vec3b>(r, c)[2];
|
|
chn_v.at<uchar>(r, c) = (v >= 250 ? 0 : 255);
|
|
}
|
|
}
|
|
cv::Mat kernel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(11, 11));
|
|
cv::morphologyEx(chn_v, chn_v, cv::MORPH_CLOSE, kernel);
|
|
cv::Rect max_validate_rect = GetMaxRect(chn_v);
|
|
if (max_validate_rect.size().area() == 0)
|
|
return cv::Mat();
|
|
return img(max_validate_rect);
|
|
}
|
|
|
|
//获取图片中面积最大的轮廓的外接矩形
|
|
cv::Rect TrafficLight::GetMaxRect(const cv::Mat &img)
|
|
{
|
|
cv::Rect max_rect;
|
|
double max_rect_size = 0;
|
|
std::vector<cv::Vec4i> hierarchy;
|
|
std::vector<std::vector<cv::Point>> contours;
|
|
cv::findContours(img, contours, hierarchy, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE); //轮廓查找
|
|
for (auto &contour: contours) //检测所找到的轮廓
|
|
{
|
|
double area = cv::contourArea(cv::Mat(contour));
|
|
if (area > (img.size().area() / 2.0))
|
|
continue;
|
|
if (area > max_rect_size)
|
|
{
|
|
max_rect_size = area;
|
|
max_rect = cv::boundingRect(contour);
|
|
}
|
|
}
|
|
return max_rect;
|
|
}
|
|
|
|
//“远大于”函数
|
|
bool TrafficLight::MuchLarger(int a, int b, double rate)
|
|
{
|
|
return (a >= (b * rate));
|
|
}
|
|
|
|
//识别灯的颜色
|
|
Light::TL_COLOR TrafficLight::GetImageColor(const cv::Mat &img, double rate)
|
|
{
|
|
int cnt_r = 0, cnt_g = 0, cnt_y = 0;
|
|
int cnt_g_less = 0, cnt_b_less = 0;
|
|
for (int r = 0; r < img.rows; r++)
|
|
{
|
|
for (int c = 0; c < img.cols; c++)
|
|
{
|
|
uns::Colors::CVColor color(img.at<cv::Vec3b>(r, c));
|
|
if (MuchLarger(color.GetR(), color.GetG(), rate) &&
|
|
MuchLarger(color.GetR(), color.GetB(), rate))
|
|
cnt_r++;
|
|
else if (MuchLarger(color.GetG(), color.GetR(), rate) &&
|
|
MuchLarger(color.GetG(), color.GetB(), rate))
|
|
cnt_g++;
|
|
else if (MuchLarger(color.GetB(), color.GetR(), rate) &&
|
|
MuchLarger(color.GetB(), color.GetG(), rate))
|
|
cnt_g++;
|
|
else if (MuchLarger(color.GetR(), color.GetB(), rate) &&
|
|
MuchLarger(color.GetG(), color.GetB(), rate))
|
|
cnt_y++;
|
|
if (color.GetG() < 110)
|
|
cnt_g_less++;
|
|
if (color.GetB() < 110)
|
|
cnt_b_less++;
|
|
}
|
|
}
|
|
LOGI("GLess: %d, BLess: %d", cnt_g_less, cnt_b_less);
|
|
int cnt_max = tri_max(cnt_r, cnt_g, cnt_y);
|
|
if ((cnt_max == cnt_r) || (cnt_max == cnt_y))
|
|
{
|
|
if ((cnt_g_less < 50) /*&& (cnt_b_less < 5)*/)
|
|
return Light::TL_COLOR::Yellow;
|
|
else
|
|
return Light::TL_COLOR::Red;
|
|
}
|
|
else if (cnt_max == cnt_g)
|
|
return Light::TL_COLOR::Green;
|
|
else
|
|
return Light::TL_COLOR::Null;
|
|
}
|
|
|
|
//整合的识别函数
|
|
Light::TL_COLOR TrafficLight::Reco(cv::Mat &img)
|
|
{
|
|
LOGI("Begin Traffic Light");
|
|
img = GetLight(img);
|
|
if (img.empty())
|
|
return Light::TL_COLOR::Null;
|
|
LOGI("Traffic Light Finished");
|
|
cv::imwrite("/sdcard/MainCar/tlr_finished.jpg", img);
|
|
return GetImageColor(img, 1.3);
|
|
}
|
|
};
|
|
|
|
//导出的识别函数
|
|
extern "C" JNIEXPORT
|
|
jint JNICALL
|
|
Java_com_uns_maincar_cpp_1interface_TrafficLight_Recognize(JNIEnv *env, jclass _this, jobject image)
|
|
{
|
|
cv::Mat img;
|
|
if(!BitmapToMat(env,image,img))
|
|
return 4;
|
|
cv::imwrite("/sdcard/MainCar/red.jpg", img);
|
|
uns::TrafficLight traffic_light;
|
|
switch(traffic_light.Reco(img))
|
|
{
|
|
case uns::Light::TL_COLOR::Red:
|
|
return 0;
|
|
case uns::Light::TL_COLOR::Yellow:
|
|
return 1;
|
|
case uns::Light::TL_COLOR::Green:
|
|
return 2;
|
|
case uns::Light::TL_COLOR::Null:
|
|
return 3;
|
|
}
|
|
return 5;
|
|
}
|
|
|
|
//导出的自检函数
|
|
extern "C" JNIEXPORT
|
|
jstring JNICALL
|
|
Java_com_uns_maincar_cpp_1interface_EnvTest_TrafficLightTest(JNIEnv *env, jclass _this)
|
|
{
|
|
std::string version = "TrafficLightReco Found, Version: " + std::string(TRAFFIC_LIGHT_RECO_VERSION);
|
|
return env->NewStringUTF(version.c_str());
|
|
} |