SIMLOCK feature

本文介绍了SIMLOCK特性的实现原理及不同平台之间的差异。探讨了Qualcomm解决方案中的具体应用,并解释了ICCcardProxy如何处理PersoLock状态变化。此外,还说明了APP在SIMLOCK特性中的作用。

1. SIMLOCK feature 由modem实现,在modem中提前设置好运营商制定的


2.  各个平台实现有差异:

    8916  platform not support slot-1 and slot-2 have the difference simlock, This is old simlock. 

    8994/8909 platform support slot-1 and slot-2 have the difference simlock, This is new simlock.


3. Qualcomm Solution: 
    00023762: What is the purpose of feature FEATURE_MMGSDI_PERSONALIZATION_SLOT2_LOCKED_ON_SLOT1 ? 


4.  tech doc:

     80-N5899-1_PERSONALIZATION FEATURE DESIGN OVERVIEW

    80-NM328-7_SIM LOCK ENGINE BASED ON HCK OVERVIEW


5.  ICCcardProxy  提供APP进行事件注册,当PersoLock状态变化由modem主动上传后,确定是否通知上层APP


6. APP仅仅提供网络锁的通知和密码输入。


7. APP调用接口传入密码,解锁由modem自完成

修改下面代码,有几个要求:1注册人脸单独拿出来。2识别出来人脸使用红框框出并且周围放上名字,需要中文显示。 CONFIG = { “feature_file”: “employee_features.json”, “attendance_file”: “attendance_records.json”, “yolo_model”: “yolov11s-face.pt”, “recog_model”: “arcfaceresnet100-8.onnx”, “detect_thresh”: 0.7, “match_thresh”: 0.65, “camera_id”: 0, “frame_size”: (640, 480) } class FaceProcessor: def init(self): self.face_model = YOLO(CONFIG[“yolo_model”]) self.recog_model = cv2.dnn.readNetFromONNX(CONFIG[“recog_model”]) self.frame_queue = Queue(maxsize=3) self.detect_queue = Queue(maxsize=2) self.feature_mgr = FeatureManager() self.attendance_log = [] threading.Thread(target=self._capture_thread, daemon=True).start() threading.Thread(target=self._detect_thread, daemon=True).start() def _capture_thread(self): cap = cv2.VideoCapture(CONFIG["camera_id"]) cap.set(3, CONFIG["frame_size"][0]) cap.set(4, CONFIG["frame_size"][1]) while True: ret, frame = cap.read() if not ret: continue if self.frame_queue.qsize() < 3: self.frame_queue.put(frame) def _detect_thread(self): while True: if self.frame_queue.empty(): time.sleep(0.01) continue frame = self.frame_queue.get() results = self.face_model(frame, imgsz=640, conf=CONFIG["detect_thresh"]) boxes = results[0].boxes.xyxy.cpu().numpy() self.detect_queue.put((frame, boxes)) def process_frame(self): if self.detect_queue.empty(): return None frame, boxes = self.detect_queue.get() for box in boxes: x1, y1, x2, y2 = map(int, box) face_img = frame[y1:y2, x1:x2] aligned_face = cv2.resize(face_img, (112, 112)) blob = cv2.dnn.blobFromImage(aligned_face, 1 / 128.0, (112, 112), (127.5, 127.5, 127.5), swapRB=True) self.recog_model.setInput(blob) feature = self.recog_model.forward().flatten() max_sim = 0 matched_id = -1 for emp_id, name, db_feat in self.feature_mgr.get_all_features(): similarity = np.dot(db_feat, feature) if similarity > max_sim and similarity > CONFIG["match_thresh"]: max_sim = similarity matched_id = emp_id # 考勤记录 if matched_id != -1: self._record_attendance(matched_id) cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(frame, f"ID:{matched_id}", (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2) return frame def _record_attendance(self, user_id): timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") new_record = {"user_id": user_id, "timestamp": timestamp} with threading.Lock(): try: with open(CONFIG["attendance_file"], "r+") as f: records = json.load(f) records.append(new_record) f.seek(0) json.dump(records, f, indent=2) except FileNotFoundError: with open(CONFIG["attendance_file"], "w") as f: json.dump([new_record], f, indent=2) if name == “main”: processor = FaceProcessor() fm = FeatureManager() sample_feature = np.random.randn(512).astype(np.float32) # 示例特征 fm.add_feature(1001, "张三", sample_feature) while True: processed_frame = processor.process_frame() if processed_frame is not None: cv2.imshow("Attendance System", processed_frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cv2.destroyAllWindows()
03-19
#include "employee_db.h" #include <stdlib.h> #include <string.h> #include <time.h> #include <math.h> #include <pthread.h> #include <stdio.h> #define INIT_CAPACITY 10 #define SIMILARITY_THRESHOLD 0.8f typedef struct { DBRECORD *records; size_t recordCount; size_t capacity; pthread_mutex_t lock; } Database; // 创建新记录 DBRECORD* createDbRecord(const char* name, const char* id, const char *feature, const char *img, const size_t featureLength, const size_t imgWidth, const size_t imgHeight) { DBRECORD *record = malloc(sizeof(DBRECORD)); if (!record) return NULL; record->name = strdup(name); record->id = strdup(id); record->date = NULL; // 将在插入时设置 record->feature = malloc(featureLength); memcpy(record->feature, feature, featureLength); //fprintf(stderr,"维度:%Iu\n", featureLength); //log record->featureLength = featureLength; record->img = malloc(imgWidth * imgHeight * 3); // 假设RGB图像 memcpy(record->img, img, imgWidth * imgHeight * 3); //printf("图片内存大小:%lu\n",imgWidth * imgHeight * 3); record->imgWidth = imgWidth; record->imgHeight = imgHeight; return record; } // 释放记录内存 void freeDbRecord(DBRECORD* dbRecord) { if (!dbRecord) return; if (dbRecord->name) free(dbRecord->name); if (dbRecord->id) free(dbRecord->id); if (dbRecord->date) free(dbRecord->date); if (dbRecord->feature) free(dbRecord->feature); if (dbRecord->img) free(dbRecord->img); } // 计算余弦相似度 float cosine_similarity(const char* v1, const char* v2, size_t length) { float dot = 0.0, denom_a = 0.0, denom_b = 0.0; for (size_t i = 0; i < length / sizeof(float); ++i) { float a = ((float*)v1)[i]; float b = ((float*)v2)[i]; dot += a * b; denom_a += a * a; denom_b += b * b; } return dot / (sqrt(denom_a) * sqrt(denom_b)); } // 数据库操作实现 static int db_insert(DBHANDLE* handle, const DBRECORD *record) { //fprintf(stderr,"进入insert\n"); // Database *db = (Database*)handle->internal; pthread_mutex_lock(&db->lock); // 检查容量并扩容 if (db->recordCount >= db->capacity) { size_t new_capacity = db->capacity * 2; DBRECORD *new_records = realloc(db->records, new_capacity * sizeof(DBRECORD)); if (!new_records) { pthread_mutex_unlock(&db->lock); return -1; } db->records = new_records; db->capacity = new_capacity; } // 设置当前时间 time_t now = time(NULL); char *date_str = malloc(20); strftime(date_str, 20, "%Y-%m-%d %H:%M:%S", localtime(&now)); // 复制记录 DBRECORD *new_rec = &db->records[db->recordCount]; *new_rec = *record; new_rec->date = date_str; db->recordCount++; pthread_mutex_unlock(&db->lock); //fprintf(stderr,"db->recordCount:%d\n",db->recordCount);// //fprintf(stderr,"db->records[0].id:%s\n",db->records[0].id);// return 0; } /*static int db_searchWithId(DBHANDLE* handle, const char* id, DBRECORD *outResult) { Database *db = (Database*)handle->internal; pthread_mutex_lock(&db->lock); //fprintf(stderr,"进入searchid\n"); // //fprintf(stderr,"db->recordCount:%d\n",db->recordCount); // //fprintf(stderr,"入参id: %s\n",id); // for (size_t i = 0; i < db->recordCount; i++) { //fprintf(stderr,"进循环\n"); // //fprintf(stderr,"db->records[%d].id:%s\n",i,db->records[i].id); if (0 == strcmp(db->records[i].id, id)) { *outResult = db->records[i]; //fprintf(stderr,"结果id:%s\n",outResult->id); // pthread_mutex_unlock(&db->lock); return 0; } } pthread_mutex_unlock(&db->lock); return -1; }*/ static int db_searchWithId(DBHANDLE* handle, const char* id, DBRECORD **outResults, int *matchCount) { Database *db = (Database*)handle->internal; pthread_mutex_lock(&db->lock); // 第一阶段:统计匹配记录数量 int count = 0; for (size_t i = 0; i < db->recordCount; i++) { if (0 == strcmp(db->records[i].id, id)) { count++; } } // 无匹配记录时直接返回 if (count == 0) { pthread_mutex_unlock(&db->lock); *matchCount = 0; *outResults = NULL; return -1; } // 动态分配结果数组 *outResults = (DBRECORD*)malloc(count * sizeof(DBRECORD)); if (*outResults == NULL) { pthread_mutex_unlock(&db->lock); return -2; // 内存分配失败 } // 第二阶段:填充匹配记录 int index = 0; for (size_t i = 0; i < db->recordCount; i++) { if (0 == strcmp(db->records[i].id, id)) { (*outResults)[index] = db->records[i]; // 结构体拷贝 index++; } } *matchCount = count; pthread_mutex_unlock(&db->lock); return 0; // 成功返回 } static int db_searchWithName(DBHANDLE* handle, const char* name, DBRECORD *outResult) { Database *db = (Database*)handle->internal; pthread_mutex_lock(&db->lock); for (size_t i = 0; i < db->recordCount; i++) { if (strcmp(db->records[i].name, name) == 0) { *outResult = db->records[i]; fprintf(stderr,"name:%s\n",outResult->name); pthread_mutex_unlock(&db->lock); return 0; } } pthread_mutex_unlock(&db->lock); return -1; } static int db_searchWithFeature(DBHANDLE* handle, const char* feature, const size_t length, DBRECORD *outResult) { Database *db = (Database*)handle->internal; pthread_mutex_lock(&db->lock); float max_sim = 0; int best_match = -1; for (size_t i = 0; i < db->recordCount; i++) { float sim = cosine_similarity(feature, db->records[i].feature, length < db->records[i].featureLength ? length : db->records[i].featureLength); if (sim > max_sim && sim > SIMILARITY_THRESHOLD) { max_sim = sim; best_match = i; } } if (best_match >= 0) { *outResult = db->records[best_match]; pthread_mutex_unlock(&db->lock); return 0; } pthread_mutex_unlock(&db->lock); return -1; } static int db_delete(DBHANDLE* handle, const char* id) { Database *db = (Database*)handle->internal; pthread_mutex_lock(&db->lock); for (size_t i = 0; i < db->recordCount; i++) { if (strcmp(db->records[i].id, id) == 0) { // 释放记录中的动态分配内存 freeDbRecord(&db->records[i]); // 移动数组元素 memmove(&db->records[i], &db->records[i+1], (db->recordCount - i - 1) * sizeof(DBRECORD)); db->recordCount--; pthread_mutex_unlock(&db->lock); return 0; } } pthread_mutex_unlock(&db->lock); return -1; } static int db_free(DBHANDLE* handle) { Database *db = (Database*)handle->internal; pthread_mutex_lock(&db->lock); for (size_t i = 0; i < db->recordCount; i++) { freeDbRecord(&db->records[i]); } free(db->records); pthread_mutex_unlock(&db->lock); pthread_mutex_destroy(&db->lock); free(db); return 0; } // 创建数据库句柄 int createDbHandle(DBHANDLE* handle) { Database *db = malloc(sizeof(Database)); if (!db) return -1; db->records = malloc(INIT_CAPACITY * sizeof(DBRECORD)); if (!db->records) { free(db); return -1; } db->recordCount = 0; db->capacity = INIT_CAPACITY; pthread_mutex_init(&db->lock, NULL); handle->internal = db; handle->insertRecord = db_insert; handle->searchWithId = db_searchWithId; handle->searchWithName = db_searchWithName; // 简化处理,同ID搜索 handle->searchWithFeature = db_searchWithFeature; handle->deleteRecord = db_delete; handle->free = db_free; return 0; } // 查询所有记录 QueryResult queryAllRecords(DBHANDLE* handle) { QueryResult result = {0}; // 实现略... return result; }我要对这部分代码写一个ppt,给我提供一个大纲
最新发布
08-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值