diff --git a/exercises/__pycache__/conv.cpython-39.pyc b/exercises/__pycache__/conv.cpython-39.pyc new file mode 100644 index 0000000..939df22 Binary files /dev/null and b/exercises/__pycache__/conv.cpython-39.pyc differ diff --git a/exercises/__pycache__/cross_entropy.cpython-39.pyc b/exercises/__pycache__/cross_entropy.cpython-39.pyc new file mode 100644 index 0000000..838cdef Binary files /dev/null and b/exercises/__pycache__/cross_entropy.cpython-39.pyc differ diff --git a/exercises/__pycache__/iou.cpython-39.pyc b/exercises/__pycache__/iou.cpython-39.pyc new file mode 100644 index 0000000..5d4c802 Binary files /dev/null and b/exercises/__pycache__/iou.cpython-39.pyc differ diff --git a/exercises/__pycache__/leaky_relu.cpython-39.pyc b/exercises/__pycache__/leaky_relu.cpython-39.pyc new file mode 100644 index 0000000..c1fb8cb Binary files /dev/null and b/exercises/__pycache__/leaky_relu.cpython-39.pyc differ diff --git a/exercises/__pycache__/maxpool.cpython-39.pyc b/exercises/__pycache__/maxpool.cpython-39.pyc new file mode 100644 index 0000000..8046ca0 Binary files /dev/null and b/exercises/__pycache__/maxpool.cpython-39.pyc differ diff --git a/exercises/__pycache__/nms.cpython-39.pyc b/exercises/__pycache__/nms.cpython-39.pyc new file mode 100644 index 0000000..71f3ec5 Binary files /dev/null and b/exercises/__pycache__/nms.cpython-39.pyc differ diff --git a/exercises/__pycache__/smooth_l1.cpython-39.pyc b/exercises/__pycache__/smooth_l1.cpython-39.pyc new file mode 100644 index 0000000..e086fc3 Binary files /dev/null and b/exercises/__pycache__/smooth_l1.cpython-39.pyc differ diff --git a/exercises/contour_detection.py b/exercises/contour_detection.py index 64ceb82..4fa3a2e 100644 --- a/exercises/contour_detection.py +++ b/exercises/contour_detection.py @@ -29,4 +29,25 @@ def contour_detection(image_path): # 7. 使用 cv2.drawContours() 在副本上绘制轮廓。 # 8. 返回绘制后的图像和轮廓列表。 # 9. 使用 try...except 处理异常。 - pass \ No newline at end of file + try: + img=cv2.imread(image_path) + if img is None: + return None,None + + gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) + _, binary=cv2.threshold(gray,127,255,cv2.THRESH_BINARY) + contours=cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) + + if len(contours)==2: + contours=contours[0] + elif len(contours)==3: + contours=contours[1] + else: + raise ValueError("error") + if not isinstance(contours,list): + contours=list(contours) + img_with_contours=img.copy() + cv2.drawContours(img_with_contours,contours,-1,(0,255,0),2) + return img_with_contours, contours + except Exception as e: + return None, None \ No newline at end of file diff --git a/exercises/conv.py b/exercises/conv.py index 0d42079..fc4dd2c 100644 --- a/exercises/conv.py +++ b/exercises/conv.py @@ -31,4 +31,43 @@ def conv2d(x, kernel): # 5. 提取输入 x 中与当前卷积核对应的区域 (patch)。 # 6. 计算 patch 和 kernel 的元素乘积之和 (np.sum(patch * kernel))。 # 7. 将结果存入输出数组 out[i, j]。 - pass \ No newline at end of file + # 获取输入和卷积核的形状 + H,W=x.shape + kH,kW=kernel.shape + # print('H,W:',H,' ',W) + # print('kH,kW:',kH,' ',kW) + out_H=H-kH+1 + out_W=W-kW+1 + out = np.zeros((out_H,out_W)) + for i in range(out_H): + for j in range(out_W): + patch=x[i:i+kH,j:j+kW] + out[i,j]=np.sum(patch*kernel) + return out + +if __name__=='__main__': + img1 = np.zeros((5,5)) + kernel1 = np.random.rand(3,3) + result1 = conv2d(img1, kernel1) + + img2 = np.eye(5) + kernel2 = np.array([[1,0,0], + [0,1,0], + [0,0,1]]) + result2 = conv2d(img2, kernel2) + expected2 = np.array([[3.,0.,0.], + [0.,3.,0.], + [0.,0.,3.]]) + + img3 = np.arange(25).reshape(5,5) + kernel3 = np.ones((3,3)) + result3 = conv2d(img3, kernel3) + expected3 = np.array([ + [ 54, 63, 72], + [ 99, 108, 117], + [144, 153, 162] + ]) + + print(result1) + print(result2) + print(result3) \ No newline at end of file diff --git a/exercises/cross_entropy.py b/exercises/cross_entropy.py index 6a70a16..f6fb95c 100644 --- a/exercises/cross_entropy.py +++ b/exercises/cross_entropy.py @@ -33,4 +33,11 @@ def cross_entropy_loss(y_true, y_pred): # 4. 计算交叉熵损失:L = - sum(y_true * log(y_pred))。 # 在 NumPy 中是 -np.sum(y_true * np.log(y_pred))。 # 5. 计算所有样本的平均损失:L / N。 - pass \ No newline at end of file + N = y_pred.shape[0] + C = y_pred.shape[1] + if y_true.ndim==1 or (y_true.ndim==2 and y_true.shape[1]==1): + y_true=np.eye(C)[y_true.reshape(-1)] + eps=1e-12 + y_pred=np.clip(y_pred,eps,1.0-eps) + loss=-np.sum(y_true*np.log(y_pred))/N + return loss \ No newline at end of file diff --git a/exercises/image_processing.py b/exercises/image_processing.py index e141a89..03d1b29 100644 --- a/exercises/image_processing.py +++ b/exercises/image_processing.py @@ -27,4 +27,14 @@ def image_processing_pipeline(image_path): # 4. 使用 cv2.GaussianBlur() 进行高斯滤波。 # 5. 使用 cv2.Canny() 进行边缘检测。 # 6. 使用 try...except 包裹代码以处理可能的异常。 - pass \ No newline at end of file + try: + img=cv2.imread(image_path) + if img is None: + return None + gray=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + + blurred=cv2.GaussianBlur(gray,(5,5),1.5) + edges=cv2.Canny(blurred,50,150) + return edges + except Exception as e: + return None \ No newline at end of file diff --git a/exercises/iou.py b/exercises/iou.py index a9ed259..5d4488d 100644 --- a/exercises/iou.py +++ b/exercises/iou.py @@ -38,4 +38,13 @@ def calculate_iou(box1, box2): # 6. 计算并集面积 union_area = box1_area + box2_area - intersection_area。 # 7. 计算 IoU = intersection_area / union_area。 # 注意处理 union_area 为 0 的情况 (除零错误)。 - pass \ No newline at end of file + x_left = max(box1[0], box2[0]) + y_top = max(box1[1], box2[1]) + x_right = min(box1[2], box2[2]) + y_bottom = min(box1[3], box2[3]) + intersection_area = max(0, x_right - x_left) * max(0, y_bottom - y_top) + box1_area=(box1[2]-box1[0])*(box1[3]-box1[1]) + box2_area=(box2[2]-box2[0])*(box2[3]-box2[1]) + union_area = box1_area + box2_area - intersection_area + IoU = 0 if union_area==0 else intersection_area / union_area + return IoU \ No newline at end of file diff --git a/exercises/leaky_relu.py b/exercises/leaky_relu.py index 6ee95a2..804a99f 100644 --- a/exercises/leaky_relu.py +++ b/exercises/leaky_relu.py @@ -27,4 +27,4 @@ def leaky_relu(x, alpha=0.01): # 1. 可以使用 np.maximum() 函数。 # 2. 计算 alpha * x。 # 3. 计算 max(alpha * x, x)。 - pass \ No newline at end of file + return np.maximum(alpha * x, x) diff --git a/exercises/maxpool.py b/exercises/maxpool.py index aceb96b..1851c3a 100644 --- a/exercises/maxpool.py +++ b/exercises/maxpool.py @@ -32,4 +32,17 @@ def maxpool(x, kernel_size, stride): # 5. 提取当前池化窗口 window = x[h_start:h_start+kernel_size, w_start:w_start+kernel_size]。 # 6. 找到窗口中的最大值 np.max(window)。 # 7. 将最大值存入输出数组 out[i, j]。 - pass \ No newline at end of file + H,W=x.shape + + out_H=(H-kernel_size)//stride+1 + out_W=(W-kernel_size)//stride+1 + + out=np.zeros((out_H,out_W)) + for i in range(out_H): + for j in range(out_W): + h_start=i*stride + w_start=j*stride + + window=x[h_start:h_start+kernel_size,w_start:w_start+kernel_size] + out[i,j]=np.max(window) + return out \ No newline at end of file diff --git a/exercises/nms.py b/exercises/nms.py index 4ece0bc..711221d 100644 --- a/exercises/nms.py +++ b/exercises/nms.py @@ -24,7 +24,16 @@ def calculate_iou(box1, box2): # 请在此处编写代码 # (与 iou.py 中的练习相同,可以复用代码或导入) # 提示:计算交集面积和并集面积,然后相除。 - pass + x_left = max(box1[0], box2[0]) + y_top = max(box1[1], box2[1]) + x_right = min(box1[2], box2[2]) + y_bottom = min(box1[3], box2[3]) + intersection_area = max(0, x_right - x_left) * max(0, y_bottom - y_top) + box1_area=(box1[2]-box1[0])*(box1[3]-box1[1]) + box2_area=(box2[2]-box2[0])*(box2[3]-box2[1]) + union_area = box1_area + box2_area - intersection_area + IoU = 0 if union_area==0 else intersection_area / union_area + return IoU def nms(boxes, scores, iou_threshold): """ @@ -52,4 +61,30 @@ def nms(boxes, scores, iou_threshold): # c. 找到 IoU 小于等于 iou_threshold 的索引 inds。 # d. 更新 order,只保留那些 IoU <= threshold 的框的索引 (order = order[inds + 1])。 # 7. 返回 keep 列表。 - pass \ No newline at end of file + if len(boxes)<=0: + return boxes + areas=[] + for box1 in boxes: + areas.append((box1[2]-box1[0])*(box1[3]-box1[1])) + boxes=np.array(boxes) + scores=np.array(scores) + order = np.argsort(scores)[::-1].tolist() + # print(order) + i=order.pop(0) + keep=[i] + for v in range(len(order)): + # print(calculate_iou(boxes[i],boxes[order[v]])) + if calculate_iou(boxes[i],boxes[order[v]])<=iou_threshold: + keep.append(order[v]) + return keep + +if __name__=='__main__': + boxes2 = [ + [10, 10, 60, 60], # 得分最高 + [15, 15, 65, 65], # 与第一个框IoU≈0.53 + [50, 50, 100, 100], # 与第一个框IoU≈0.11 + [150, 150, 200, 200] # 完全独立 + ] + scores2 = [0.9, 0.85, 0.8, 0.75] + result2 = nms(boxes2, scores2, 0.5) + print(result2) diff --git a/exercises/smooth_l1.py b/exercises/smooth_l1.py index 7847a04..82688ca 100644 --- a/exercises/smooth_l1.py +++ b/exercises/smooth_l1.py @@ -30,4 +30,8 @@ def smooth_l1(x, sigma=1.0): # 3. 对满足条件的元素应用第一个公式 (0.5 * (sigma * x)**2)。 # 4. 对不满足条件的元素应用第二个公式 (|x| - 0.5 / sigma2)。 # 5. 可以使用 np.where() 来根据条件选择应用哪个公式。 - pass \ No newline at end of file + sigma2=sigma**2 + t=1.0/sigma2 + ax=np.abs(x) + loss=np.where(ax