使用Python-OpenCV去除图像白色背景污渍的问题求助
OpenCV背景纯白处理问题求助
我是OpenCV新手,正在完成大学作业,需要把原本带污渍的白色背景图像处理成完全纯白背景,保留完整物体。我写了代码,但运行后只得到物体的黑色边界框,达不到预期效果。
原图:
结果图:
我的代码:
import cv2 import numpy as np image = cv2.imread('./MCP_tmp_picam_final.jpg') original = image.copy() gray = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY) blur = cv2.GaussianBlur(gray, (3,3), 0) thresh = cv2.adaptiveThreshold(blur,225,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,21,2) # Draw boundingboxes onto a mask mask = np.zeros(original.shape[:2], dtype=np.uint8) cnts,_ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) for i, c in enumerate(cnts): area = cv2.contourArea(c) # Ignore contours that are too small or too large if area < 1000 or 100000 < area: #100000 continue rect = cv2.minAreaRect(c) #print(rect) box = cv2.boxPoints(rect) box = np.int0(box) cv2.drawContours(mask, [box], 0, (255,255,255), 2) cv2.drawContours(image,[box],0,(0,0,255),2) # Bitwise-and for result result = cv2.bitwise_and(original, original, mask=mask) result[mask==0] = (255,255,255) cv2.imshow('result', result) cv2.imshow('mask', mask) cv2.imshow('image', image) cv2.waitKey()
问题原因与解决方法
问题出在mask的绘制逻辑:你调用cv2.drawContours时使用了厚度参数2,这只会在mask上画出轮廓的边框,内部区域仍为黑色。后续的bitwise_and操作只会保留边框区域,其余区域被设为白色,因此最终结果只有黑色边框。
修改关键:
将绘制mask时的厚度参数从2改为-1,-1表示填充整个轮廓内部,让mask对应物体的区域全部变为白色。
修改后的完整代码:
import cv2 import numpy as np image = cv2.imread('./MCP_tmp_picam_final.jpg') original = image.copy() gray = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY) blur = cv2.GaussianBlur(gray, (3,3), 0) thresh = cv2.adaptiveThreshold(blur,225,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,21,2) # Draw boundingboxes onto a mask mask = np.zeros(original.shape[:2], dtype=np.uint8) cnts,_ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) for i, c in enumerate(cnts): area = cv2.contourArea(c) # Ignore contours that are too small or too large if area < 1000 or 100000 < area: continue rect = cv2.minAreaRect(c) box = cv2.boxPoints(rect) box = np.int0(box) # 修改厚度为-1,填充轮廓内部 cv2.drawContours(mask, [box], 0, 255, -1) cv2.drawContours(image,[box],0,(0,0,255),2) # Bitwise-and for result result = cv2.bitwise_and(original, original, mask=mask) result[mask==0] = (255,255,255) cv2.imshow('result', result) cv2.imshow('mask', mask) cv2.imshow('image', image) cv2.waitKey()
额外提示:
如果目标物体没有被正确选中,可以调整轮廓筛选的面积范围(area < 1000和100000 < area),确保只保留需要的物体轮廓。
内容的提问来源于stack exchange,提问作者Mohamed Lamine Duchme Minani
相关产品推荐
相关产品推荐

