How to detect area of pixels with the same color using OpenCV
使用OpenCV Python,我想知道哪种方法最好的方法是识别图像中具有特定颜色像素高度集中的区域,并可能通过在它们周围绘制一个圆来对其进行"标记"。铅>
我尝试使用findContours方法,但这很混乱...
我的直觉告诉我,我必须设置颜色的相邻像素的范围[min:max],然后确定该区域的中心,并在其中绘制'O'...
================================================ =======================
第一个图像是处理BGR图像(到HSV并处理几个色罩)后得到的示例:
检测前的图像
使用
这是主要思想
- 将图像转换为HSV格式
- 使用较低/较高的阈值执行颜色分割
- 进行形态学转换以消除小噪声
- 查找轮廓并求和轮廓区域
我假设您要检测黄色区域。我们首先将图像转换为HSV格式,然后使用上下限
的颜色阈值
1 2 | lower = np.array([33, 0, 238], dtype="uint8") upper = np.array([135, 189, 255], dtype="uint8") |
这将导致分段蒙版
从这里我们执行形态转换以消除小噪声
接下来,我们找到轮廓并用
总面积
87781.5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | import numpy as np import cv2 image = cv2.imread('2.jpg') original = image.copy() image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) lower = np.array([33, 0, 238], dtype="uint8") upper = np.array([135, 189, 255], dtype="uint8") mask = cv2.inRange(image, lower, upper) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3)) opening = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel, iterations=1) cnts = cv2.findContours(opening, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = cnts[0] if len(cnts) == 2 else cnts[1] area = 0 for c in cnts: area += cv2.contourArea(c) cv2.drawContours(original,[c], 0, (0,0,0), 2) print(area) cv2.imshow('mask', mask) cv2.imshow('original', original) cv2.imshow('opening', opening) cv2.waitKey() |
您可以使用此脚本查找颜色阈值范围
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | import cv2 import sys import numpy as np def nothing(x): pass useCamera=False # Check if filename is passed if (len(sys.argv) <= 1) : print("'Usage: python hsvThresholder.py <ImageFilePath>' to ignore camera and use a local image.") useCamera = True # Create a window cv2.namedWindow('image') # create trackbars for color change cv2.createTrackbar('HMin','image',0,179,nothing) # Hue is from 0-179 for Opencv cv2.createTrackbar('SMin','image',0,255,nothing) cv2.createTrackbar('VMin','image',0,255,nothing) cv2.createTrackbar('HMax','image',0,179,nothing) cv2.createTrackbar('SMax','image',0,255,nothing) cv2.createTrackbar('VMax','image',0,255,nothing) # Set default value for MAX HSV trackbars. cv2.setTrackbarPos('HMax', 'image', 179) cv2.setTrackbarPos('SMax', 'image', 255) cv2.setTrackbarPos('VMax', 'image', 255) # Initialize to check if HSV min/max value changes hMin = sMin = vMin = hMax = sMax = vMax = 0 phMin = psMin = pvMin = phMax = psMax = pvMax = 0 # Output Image to display if useCamera: cap = cv2.VideoCapture(0) # Wait longer to prevent freeze for videos. waitTime = 330 else: img = cv2.imread(sys.argv[1]) output = img waitTime = 33 while(1): if useCamera: # Capture frame-by-frame ret, img = cap.read() output = img # get current positions of all trackbars hMin = cv2.getTrackbarPos('HMin','image') sMin = cv2.getTrackbarPos('SMin','image') vMin = cv2.getTrackbarPos('VMin','image') hMax = cv2.getTrackbarPos('HMax','image') sMax = cv2.getTrackbarPos('SMax','image') vMax = cv2.getTrackbarPos('VMax','image') # Set minimum and max HSV values to display lower = np.array([hMin, sMin, vMin]) upper = np.array([hMax, sMax, vMax]) # Create HSV Image and threshold into a range. hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) mask = cv2.inRange(hsv, lower, upper) output = cv2.bitwise_and(img,img, mask= mask) # Print if there is a change in HSV value if( (phMin != hMin) | (psMin != sMin) | (pvMin != vMin) | (phMax != hMax) | (psMax != sMax) | (pvMax != vMax) ): print("(hMin = %d , sMin = %d, vMin = %d), (hMax = %d , sMax = %d, vMax = %d)" % (hMin , sMin , vMin, hMax, sMax , vMax)) phMin = hMin psMin = sMin pvMin = vMin phMax = hMax psMax = sMax pvMax = vMax # Display output image cv2.imshow('image',output) # Wait longer to prevent freeze for videos. if cv2.waitKey(waitTime) & 0xFF == ord('q'): break # Release resources if useCamera: cap.release() cv2.destroyAllWindows() |