switch_check的滑动

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true" android:drawable="@drawable/icon_switch_checked"></item>
    <item android:drawable="@drawable/icon_switch_unchecked"></item>
</selector>

lock_car = (ImageView) findViewById(R.id.lock_car);
lock_car.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        v.setSelected(!v.isSelected());
    }
});

<ImageView
    android:id="@+id/lock_car"
    style="@style/PersonInfoRightTextItem"
    android:src="@drawable/switch_button" />

void AiDetection::calculateBrightness(cv::Mat &_image, int &brightnessLevel) { auto start_b = std::chrono::high_resolution_clock::now(); // 获取图像高度并计算上半部分的高度 // int height = _image.size().height; // int halfHeight = height / 2; // // 提取图像上半部分 // cv::Mat upperHalfImage = _image(cv::Range(0, halfHeight), cv::Range::all()); cv::Mat grayscaleImage; cv::cvtColor(_image, grayscaleImage, cv::COLOR_BGR2GRAY); // 转为灰度图 // 计算灰度图像的平均亮度 cv::Scalar meanBrightness = cv::mean(grayscaleImage); int brightness = static_cast<int>(meanBrightness.val[0]); // cv::Scalar median; // cv::medianBlur(grayscaleImage, grayscaleImage, 1); // cv::minMaxLoc(grayscaleImage, nullptr, &median.val[0], nullptr, nullptr, cv::Mat()); // int brightness = static_cast<int>(median.val[0]); if (brightness < 40) { LOG_TRACE("Brightness Level: very dark"); brightnessLevel = nav2_msgs::action::Brightness::VERY_DARK; } else if (brightness < 75) { LOG_TRACE("Brightness Level: dark"); brightnessLevel = nav2_msgs::action::Brightness::GENERALLY_DARK; } else if (brightness < 140) { LOG_TRACE("Brightness Level: normal"); brightnessLevel = nav2_msgs::action::Brightness::GENERALLY_BRIGHT; } else { LOG_TRACE("Brightness Level: light"); brightnessLevel = nav2_msgs::action::Brightness::VERY_BRIGHT; } auto end_b = std::chrono::high_resolution_clock::now(); std::chrono::duration<double> diff_b = end_b - start_b; LOG_TRACE("*************brightness detect time: {} *************", diff_b.count()); } void AiDetection::optimizedBrightnessCalculation(cv::Mat &_image, int &brightnessLevel) { auto start_b = std::chrono::high_resolution_clock::now(); // 定义检测区域,左上角 (360, 0),右下角 (900, 400) cv::Rect roi(360, 0, 900 - 360, 400 - 0); cv::Mat targetArea = _image(roi); // 图像预处理:去噪 cv::Mat denoisedImage; cv::medianBlur(targetArea, denoisedImage, 5); // 使用5x5的中值滤波器去噪 // 转换为灰度图像 cv::Mat grayscaleImage; cv::cvtColor(denoisedImage, grayscaleImage, cv::COLOR_BGR2GRAY); // 计算灰度图像的平均亮度 cv::Scalar meanBrightness = cv::mean(grayscaleImage); int brightness = static_cast<int>(meanBrightness.val[0]); // 根据亮度值确定亮度级别 if (brightness < 40) { LOG_TRACE("Brightness Level: very dark"); brightnessLevel = nav2_msgs::action::Brightness::VERY_DARK; } else if (brightness < 95) { LOG_TRACE("Brightness Level: dark"); brightnessLevel = nav2_msgs::action::Brightness::GENERALLY_DARK; } else if (brightness < 140) { LOG_TRACE("Brightness Level: normal"); brightnessLevel = nav2_msgs::action::Brightness::GENERALLY_BRIGHT; } else { LOG_TRACE("Brightness Level: light"); brightnessLevel = nav2_msgs::action::Brightness::VERY_BRIGHT; } auto end_b = std::chrono::high_resolution_clock::now(); std::chrono::duration<double> diff_b = end_b - start_b; LOG_TRACE("*************brightness level count: {} *************", brightness); LOG_TRACE("*************brightness detect time: {} *************", diff_b.count()); }void AiServer::ai_detect() { enum State { NORMAL_STATE, DARK_CHECK_STATE, SUSTAIN_PUBLISH_STATE, POST_SUSTAIN_CHECK_STATE }; int check_mem_count = 0; State current_state = NORMAL_STATE; int dark_check_counter = 0; int brightness_dark_check_counts[2] = {0}; int sustain_publish_counter = 0; int sustain_publish_interval_counter = 0; int post_sustain_check_counter = 0; int post_sustain_brightness_counts[2] = {0}; try { std::string raw_path; cv::Mat frame; int queue_size = 0; TOF_Frame tof_frame; cv::Mat R = cv::Mat::eye(3, 3, CV_64F); cv::Size img_size(rgb_tof_dev_w_h_tmp.rgb_w, rgb_tof_dev_w_h_tmp.rgb_h); cv::Mat mapx, mapy; cv::fisheye::initUndistortRectifyMap(camera_matrix, distortion_coefficients, R, camera_matrix, img_size, CV_32FC1, mapx, mapy); cv::Mat resultImg; nav2_msgs::action::AiDetection_Result brightness_level; int currentBrightnessLevel; int brightness_calculation_count = 0; int brightness_low_streak = 0; int brightness_high_streak = 0; double loop_frequency_ = 10; rclcpp::WallRate r(loop_frequency_); rclcpp::Rate a(1); cv::Mat show_image; sensor_msgs::msg::Image show_Image; sensor_msgs::msg::PointCloud pointcloud; bool use_dark_method = false; bool use_pointcloud = true; int dark_result_publish_count = 0; int get_frame_error = 0; int dark_result_count = 0; int result_count = 0; robot_msgs::msg::ErrorInfo error_info; int block_counter = 0; int unblock_counter = 0; const int BLOCK_THRESHOLD = 20; // 2秒 const int UNBLOCK_THRESHOLD = 20; bool isblocked = false; cv::Rect seg_roi(30,208,1024,512); while (true) { if(debug_){ check_mem_count++; if(check_mem_count > 100){ check_mem_count = 0; trace_mem(); } } if(is_ai_detection_){ LOG_TRACE("===================================start========================================="); auto start = std::chrono::high_resolution_clock::now(); if(camera_base_->getFrame(raw_path, frame,tof_frame, queue_size)) { get_frame_error = 0; frame_error_ = false; auto end_getFrame = std::chrono::high_resolution_clock::now(); std::chrono::duration<double> diff_get_frame = end_getFrame - start; LOG_TRACE("camera_base_->getFrame size: {}, time: {} ",queue_size, diff_get_frame.count()); { auto start_dection = std::chrono::high_resolution_clock::now(); if(is_edge_detection_){ ai_detection_->edge_detection(frame, *tof_frame.pRgb2TofPixelCoord, tof_frame.pointcloud); } else if (is_seg_edge_detection_){ ai_detection_->seg_edge_detection(frame, *tof_frame.pRgb2TofPixelCoord, tof_frame.pointcloud); } else{ ai_detection_->detection(frame, *tof_frame.pRgb2TofPixelCoord, tof_frame.pointcloud, avoidence_size, sensitivity_level); } LOG_TRACE("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!sensitivity_level: {} !!!!!!!!!!!!!!!!!!!!!!!!!!!!!1:detect_only,2:no_believe_seg,3:yes_believe_seg", sensitivity_level); LOG_TRACE("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!avoidence_size: {} !!!!!!!!!!!!!!!!!!!!!!!!!!!!!", avoidence_size); auto end_dection = std::chrono::high_resolution_clock::now(); std::chrono::duration<double> diff_dection = end_dection - start_dection; LOG_TRACE("*************detection Time to run:{} seconds.*************",diff_dection.count()); } // if (result_count % 5 == 0){ // if(is_seg_edge_detection_){ // cv::Rect build_roi(0,208,1024,512); // show_image = ai_detection_->getResultImage(frame, *tof_frame.pRgb2TofPixelCoord, build_roi); // cv::Mat pub_image; // int resize_W = 240; // int resize_H = 136; // cv::resize(show_image, pub_image, cv::Size(resize_W, resize_H)); // std::string dir_path = "/home/sunrise/result"; // std::string filename = dir_path + "/result_" + std::to_string(result_count) + ".jpg"; // cv::imwrite(filename, pub_image); // } // else{ // show_image = ai_detection_->getResultImage(frame, *tof_frame.pRgb2TofPixelCoord, seg_roi); // cv::Mat pub_image; // int resize_W = 240; // int resize_H = 136; // cv::resize(show_image, pub_image, cv::Size(resize_W, resize_H)); // std::string dir_path = "/home/sunrise/result"; // std::string filename = dir_path + "/result_" + std::to_string(result_count) + ".jpg"; // cv::imwrite(filename, pub_image); // } // } result_count++; brightness_calculation_count++; if (brightness_calculation_count >= 5) { if (use_dark_method) { ai_detection_->calculateDarkBrightness(frame, currentBrightnessLevel); } else { ai_detection_->optimizedBrightnessCalculation(frame, currentBrightnessLevel); } brightness_calculation_count = 0; // 状态机处理 switch(current_state) { case DARK_CHECK_STATE: if(++dark_check_counter == 1) { // 首次进入时记录 LOG_TRACE("Enter DARK_CHECK_STATE, start 30 brightness checks"); } if(currentBrightnessLevel <= 1) brightness_dark_check_counts[0]++; else brightness_dark_check_counts[1]++; if(++dark_check_counter >= 30) { if(brightness_dark_check_counts[0] > brightness_dark_check_counts[1]) { publishBrightnesslevel(0, brightness_level); current_state = NORMAL_STATE; use_dark_method = false; LOG_TRACE("Exit DARK_CHECK_STATE: Bright dominant"); } else { current_state = SUSTAIN_PUBLISH_STATE; sustain_publish_counter = 0; sustain_publish_interval_counter = 0; LOG_TRACE("Exit DARK_CHECK_STATE: Dark dominant"); } memset(brightness_dark_check_counts, 0, sizeof(brightness_dark_check_counts)); dark_check_counter = 0; } break; case POST_SUSTAIN_CHECK_STATE: if(post_sustain_check_counter == 0) { // 首次进入时记录 LOG_TRACE("Enter POST_SUSTAIN_CHECK_STATE, start 10 checks"); } if(currentBrightnessLevel <= 1) post_sustain_brightness_counts[0]++; else post_sustain_brightness_counts[1]++; if(++post_sustain_check_counter >= 10) { LOG_TRACE("PostCheck results - Bright:{} Dark:{}", post_sustain_brightness_counts[0], post_sustain_brightness_counts[1]); if(post_sustain_brightness_counts[0] > post_sustain_brightness_counts[1]) { publishBrightnesslevel(0, brightness_level); current_state = NORMAL_STATE; use_dark_method = false; LOG_TRACE("Return to NORMAL_STATE from POST_CHECK"); } else { current_state = SUSTAIN_PUBLISH_STATE; sustain_publish_counter = 0; sustain_publish_interval_counter = 0; LOG_TRACE("Re-enter SUSTAIN_PUBLISH_STATE"); } memset(post_sustain_brightness_counts, 0, sizeof(post_sustain_brightness_counts)); post_sustain_check_counter = 0; } break; } // 原始区间判断逻辑保持不变 if (currentBrightnessLevel == 0 || currentBrightnessLevel == 1) { brightness_high_streak++; brightness_low_streak = 0; } else if (currentBrightnessLevel == 2 || currentBrightnessLevel == 3) { brightness_low_streak++; brightness_high_streak = 0; } else { brightness_high_streak = 0; brightness_low_streak = 0; } } // 状态触发逻辑 if ((brightness_high_streak >= 12 || brightness_low_streak >= 10) && current_state == NORMAL_STATE) { publishBrightnesslevel(currentBrightnessLevel, brightness_level); LOG_TRACE("Publish Brightness_level:{}", currentBrightnessLevel); brightness_high_streak = 0; brightness_low_streak = 0; use_dark_method = (currentBrightnessLevel >= 2); if(use_dark_method) { current_state = DARK_CHECK_STATE; dark_check_counter = 0; memset(brightness_dark_check_counts, 0, sizeof(brightness_dark_check_counts)); } } // 持续发布状态处理 if(current_state == SUSTAIN_PUBLISH_STATE) { if(++sustain_publish_counter >= 600) { // 60秒 current_state = POST_SUSTAIN_CHECK_STATE; post_sustain_check_counter = 0; memset(post_sustain_brightness_counts, 0, sizeof(post_sustain_brightness_counts)); } else if(++sustain_publish_interval_counter >= 100) { // 10秒 publishBrightnesslevel(2, brightness_level); LOG_TRACE("Sustain Publish Brightness_level:2"); sustain_publish_interval_counter = 0; } } ai_detection_->checkblock(frame, isblocked); if(isblocked) { unblock_counter = 0; // 重置解除计数器 if(!blocked_error_) { if(++block_counter >= BLOCK_THRESHOLD) { LOG_TRACE("Camera blocked for 2 seconds!"); blocked_error_ = true; publishError(error_info); } } } else { block_counter = 0; // 重置触发计数器 if(blocked_error_) { if(++unblock_counter >= UNBLOCK_THRESHOLD) { LOG_TRACE("Camera unblocked for 2 seconds!"); blocked_error_ = false; unblock_counter = 0; } } } // 保持原有图像发布逻辑 if(debug_){ if (show_image_pub_->get_subscription_count() > 0) { if(is_seg_edge_detection_){ cv::Rect build_roi(30,208,1024,512); show_image = ai_detection_->getResultImage(frame, *tof_frame.pRgb2TofPixelCoord, build_roi); cv::Mat pub_image; int resize_W = 240; int resize_H = 136; cv::resize(show_image, pub_image, cv::Size(resize_W, resize_H)); cv::cvtColor(pub_image, pub_image, cv::COLOR_BGR2RGB); publishImage(show_image_pub_, pub_image); } else{ show_image = ai_detection_->getResultImage(frame, *tof_frame.pRgb2TofPixelCoord, seg_roi); cv::Mat pub_image; int resize_W = 240; int resize_H = 136; cv::resize(show_image, pub_image, cv::Size(resize_W, resize_H)); cv::cvtColor(pub_image, pub_image, cv::COLOR_BGR2RGB); publishImage(show_image_pub_, pub_image); } } } // 保持原有点云发布逻辑 if (is_seg_edge_detection_){ if (show_seg_pointcloud_pub_->get_subscription_count() > 0) { pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_result; ai_detection_->getResultPointclound(cloud_result); sensor_msgs::msg::PointCloud ros_pointcloud; conversion_pcl_to_ros(cloud_result, ros_pointcloud); rclcpp::Time t(tof_frame.host_ts, RCL_SYSTEM_TIME); ros_pointcloud.header.stamp = t; publishPointCloud(show_seg_pointcloud_pub_, ros_pointcloud); } } if (show_det_pointcloud_pub_->get_subscription_count() > 0) { pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_result; ai_detection_->getResultPointclound(cloud_result); sensor_msgs::msg::PointCloud ros_pointcloud; conversion_pcl_to_ros(cloud_result, ros_pointcloud); rclcpp::Time t(tof_frame.host_ts, RCL_SYSTEM_TIME); ros_pointcloud.header.stamp = t; publishPointCloud(show_det_pointcloud_pub_, ros_pointcloud); } auto end = std::chrono::high_resolution_clock::now(); std::chrono::duration<double> diff = end - start; LOG_TRACE("*************all detection Time to run:{} seconds.*************",diff.count()); if (!r.sleep()) { RCLCPP_WARN(logger_, "ai_detect loop missed its desired rate of %.4fHz \n", loop_frequency_); } LOG_TRACE("================================end============================================"); } else { LOG_WARN("getFrame time out!"); get_frame_error++; if (get_frame_error >= 10){ frame_error_ = true; } } } else{ a.sleep(); } } } catch (const std::exception &e) { RCLCPP_ERROR(logger_, "%s", e.what()); LOG_ERROR("*************all detection run exception:{} *************", e.what()); return; } }这是现在暂时使用的环境光检测流程和两种环境光计算方法,进行完整修改优化或者替换,方便能够快速使用编译测试
05-28
//受信データのヘッダーサイズ #define HEADER_SIZE 3 //受信データサイズ部分のサイズ #define SIZE_DATA_SIZE 2 //周期時間 (us) #define CYCLE_TIME 5000 //Read処理開始タイマ (ms) #define READ_TIME 970 unsigned long time_last_sending; unsigned long time_last_reading; //アニメーション送信時受信完了シグナル byte animation_return[3] = {0x00, 0x01, 0x02}; //アニメーション再生完了シグナル byte animation_end[3] = {0x0F, 0x0E, 0x0D}; //アニメーションデータ長保存用 uint16_t animation_size = 0; //受信タイプを定義 typedef enum _recv_type { //指示タイプ: 0x00 (切断) Disconnect, //指示タイプ: 0x01 (接続) Connect, //指示タイプ: 0x02 (アニメーション) Animation, //指示タイプ: 0x03 (点灯) TurnOn, //指示タイプ: 0x04 (アニメーション送信開始) StartAnimation, //指示タイプ: 0x05 (アニメーション送信中止) StopAnimation, //指示タイプ: 0x06 (アニメーション書き込み開始) WriteAnimation } recv_type; //受信データ処理 void g_Main() { // 定期送信フラグ bool can_send_phase = false; // Read開始フラグ bool can_do_read = false; //初期化フェーズ送信フラグ bool can_send_initial = false; // データチェックするかどうかのフラグ bool can_check_data_type = false; //アニメーションデータ設定フラグ bool can_set_animation = false; //ヘッダーサイズ確認フラグ bool can_get_headder_size = true; //アニメーション送信フラグ bool can_send_animation = false; //アニメーションヘッダ確認フラグ bool can_check_animation_header = false; //アニメーションデータチェックフラグ bool can_check_animation_data = false; //Readフラグ bool read_flag = false; // 送信フェーズ設定 uint8_t phase_num = 0; //受信データの残サイズ uint16_t data_size = 0; uint16_t num_animation_counter = 0; uint16_t num_send_animation_counter = 0; int anim_start_pos = 0; int anim_send_size = 0; int data_type = 0; while(1) { //データサイズを取得 if((SerialUSB.available() >= HEADER_SIZE) && (can_get_headder_size == true)) { SerialPrint("Get Header"); //データサイズ確認 data_size = f_CalculateDataSize(); //データタイプ保持 data_type = SerialUSB.read(); //フラグ管理 can_check_data_type = true; can_get_headder_size = false; if((recv_type)data_type == Animation) { can_do_read = false; can_check_animation_header = true; num_send_animation_counter = 0; } } //アニメーションヘッダ情報取得 if((can_check_animation_header) && (SerialUSB.available() >= 2)) { SerialPrint("can_check_animation_header"); //アニメーションヘッダ書き込み g_SetAnimationHeader(num_animation_counter); //残受信データ情報更新 data_size = data_size - 2; //アニメーションサイズ保持 animation_size = data_size; //データ受信完了シグナル送信 SerialUSB.write(animation_return, 3); //アニメーションデータ書き込みモードへ can_check_animation_header = false; can_check_animation_data = true; if(data_size < 250) { anim_send_size = data_size; } else { anim_send_size = 250; } } //アニメーションデータ取得 if((can_check_animation_data == true) && (SerialUSB.available() >= anim_send_size)) { SerialPrint("can_check_animation_data"); //残受信データ更新 data_size = data_size - anim_send_size; //アニメーションデータ書き込み g_SetAnimationDuty(anim_start_pos, anim_send_size, num_animation_counter); //書き込み開始位置更新 anim_start_pos += anim_send_size; //受信完了時処理 if(data_size == 0) { num_animation_counter++; anim_start_pos = 0; anim_send_size = 0; can_check_data_type = false; can_check_animation_data = false; can_get_headder_size = true; } else if(data_size < 250) { anim_send_size = data_size; } else { anim_send_size = 250; } //受信完了シグナル送信 SerialUSB.write(animation_return, 3); } //全データを取得後、タイプ別に処理 else if((can_check_data_type == true) && (SerialUSB.available() >= data_size)) { SerialPrint("can_check_data_type"); SerialPrint(String(data_type) + " " + String(data_size) + "byte"); can_check_data_type = false; can_get_headder_size = true; //切断コマンド if( (recv_type)data_type == Disconnect) { can_send_phase = false; can_do_read = false; break; } //接続コマンド else if( (recv_type)data_type == Connect) { g_ReadDeviceID(data_size); can_send_phase = true; can_send_initial = true; can_do_read = false; phase_num = 0; g_ReadConfigEeprom(); } //点灯コマンド else if( (recv_type)data_type == TurnOn) { can_send_animation = false; g_RecvOneShot(data_size); can_do_read = true; } //アニメーション開始コマンド else if( (recv_type)data_type == StartAnimation) { can_send_animation = true; can_do_read = false; } //アニメーション停止コマンド else if( (recv_type)data_type == StopAnimation) { can_send_animation = false; can_do_read = true; } //アニメーション書き込みコマンド else if( (recv_type)data_type == WriteAnimation) { can_do_read = false; num_animation_counter = 0; } else { //continue; } } if((micros() - time_last_sending) > (CYCLE_TIME - 30)) { } else { //残周期時間分ディレイ delayMicroseconds(CYCLE_TIME - (micros() - time_last_sending)); } time_last_sending = micros(); //通常or初期化phaseの判定 if(can_send_initial == true) { g_SendInitializeData(); time_last_sending = micros(); phase_num = 0; can_send_initial = false; } else if(can_send_phase == true) { //1フェーズ送信 g_SendOnePhase(phase_num); //Duty情報処理開始タイミングチェック if(can_do_read == true) { if(phase_num == 0 && millis() - time_last_reading > READ_TIME) { read_flag = true; } } else { time_last_reading = millis(); read_flag = false; } if(read_flag == true) { // 5ms Wait 処理 if((micros() - time_last_sending) > (CYCLE_TIME - 30)) { } else { //残周期時間分ディレイ delayMicroseconds(CYCLE_TIME - (micros() - time_last_sending)); } time_last_sending = micros(); g_TreatRead(phase_num); if(phase_num == 5) { g_SendReadData(); // Read 終了時に Error Clear 送信 g_SendErrorClear(); time_last_reading = millis(); read_flag = false; } } else if((num_send_animation_counter == 0) && (phase_num != 5)) { //アニメーション再生開始が1フェーズ目からになるように調整 } //フェーズの奇数番目のみアニメーションDuty書き換え else if((can_send_animation == true) && (phase_num % 2 == 1)) { //Duty情報更新 g_RenewDutyData(num_send_animation_counter, num_animation_counter); //アニメーション再生回数インクリメント num_send_animation_counter++; //アニメーション再生完了時処理 if(num_send_animation_counter == animation_size) { can_send_animation = false; num_send_animation_counter = 0; //アニメーション再生完了シグナル送信 SerialUSB.write(animation_end, 3); } } //フェーズ情報管理 phase_num++; phase_num = phase_num % NUM_OF_PHASE; } } } //データサイズを計算 uint16_t f_CalculateDataSize() { uint16_t recv_size = SerialUSB.read(); recv_size <<= 8; recv_size += SerialUSB.read(); return recv_size; }
最新发布
10-28
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值