As the title suggests, the image consists of solid color blocks. I want to extract all the color blocks from the image and separate them individually. I've made many attempts, but the results haven't been very satisfactory:
- Extracting by automatically calculating the threshold, unfortunately, doesn't work for all color blocks.
t, _ = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
_, target = cv2.threshold(img, t, 255, cv2.THRESH_BINARY_INV)
cnts, hierarchys = cv2.findContours(target, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
- After edge detection and a series of morphological operations for contour extraction, there are still many unwanted extra parts.
gray_temp = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = 255 - cv2.Canny(gray_temp, 25, 50)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
edges = cv2.erode(edges, kernel, iterations=1)
cnts, hierarchys = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
So, what I've been thinking is whether I could first extract all the colors from the image and then use the color information to extract the blocks.
Ready to give it a try, I attempted to use numpy to retrieve color information, but the obtained color information surprised me. Pixels that appear to be the same color don't have identical RGB values.
I felt a bit disheartened. I searched Google again and found a promising library called "extcolors." I was excited, as if I had glimpsed a ray of hope. However, reality dealt me a blow - it requires setting a tolerance. The frustrating part is that this tolerance varies for each image, and different values yield vastly different results.
So, my question is, is there any effective method that could allow me to obtain all the colors, or are there alternative ways to extract the color blocks with high quality?