【问题标题】:Differentiate dark and light areas in image [closed]区分图像中的暗区和亮区
【发布时间】:2018-01-05 12:58:24
【问题描述】:

我的问题是我想区分下图中的明暗区域以生成二进制蒙版。

https://i.stack.imgur.com/7ZRKB.jpg

输出的近似值可以是:

https://i.stack.imgur.com/2UuJb.jpg

我已经尝试了很多东西,但结果仍然有一些噪音或者我丢失了很多数据,如下图所示:

https://i.stack.imgur.com/hUyjY.png

我已经将 python 与 opencv 和 numpy、高斯过滤器、打开、关闭等一起使用... 有人对此有什么想法吗?

提前致谢!

【问题讨论】:

  • 请提供您目前的解决方案。
  • 我遵循了这条管道: 1.- 以灰度打开图像。 2.- 强制对比度(白色为 175,深色为 177)。 3.- 打开 x2 迭代。 4.- 扩张。 5.- 使用内核大小为 50 的高斯滤波器。 6.- 对结果图像进行阈值处理。
  • 我的意思是你的实际代码。

标签: python opencv computer-vision


【解决方案1】:

我首先使用 pyrDown 减小了图像的大小,然后使用 CLAHE 来均衡直方图。我使用了中值模糊,因为这将创建补丁然后使用打开 3 次。之后是一个简单的 binary_inv 阈值。如果要获取原始图像大小,请在图像上使用 cv2.pyrUp。通过调整参数,您可以获得更好的结果。

import cv2

image = cv2.imread("7ZRKB.jpg",0)
image = cv2.pyrDown(image)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(16,16))
image = clahe.apply(image)

image = cv2.medianBlur(image, 7)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
image = cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel, iterations=3)

ret,image = cv2.threshold(image, 150, 255, cv2.THRESH_BINARY_INV)
cv2.imshow("image",image)

cv2.waitKey()
cv2.destroyAllWindows()

结果:

【讨论】:

  • 很好!!真的很酷的结果,谢谢!我对您的代码有一个疑问:为什么您以这种方式定义内核而不是使用 numpy 数组?您的方式会产生不同的结果还是提高计算速度?
  • 如果您愿意,可以更轻松地修改结构元素。通过使用 cv2.MORPH_ELLIPSE 它将创建一个带有椭圆作为掩码的矩阵。还有一个 cv2.MORPH_CROSS 但它不适用于这里。我也不需要导入 numpy(反正 cv2 使用它)
【解决方案2】:

代码,对不起!

image = cv2.imread(IMAGE_PATH, 0)
image = cv2.equalizeHist(image)
kernel = np.ones((5, 5),np.uint8)
image = cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel, iterations=2)
image = cv2.dilate(image,kernel,iterations = 1)

image = cv2.GaussianBlur(image, (13, 13), 3)

ret,thresh1 = cv2.threshold(image, 100, 255, cv2.THRESH_BINARY)

cv2.imwrite(SAVE_PATH, thresh1)

【讨论】:

  • 这个产生的图像与您的第一篇文章完全不同。
  • 对不起!你是对的,我为此做了很多代码,我把一个和另一个混淆了......我将用好的代码更新答案,对不起,谢谢!
  • @AlfonsoMartinezLarraz 这应该是您问题的答案吗?
【解决方案3】:
image = cv2.imread(IMAGE)

#Change to HSV:
cv2.cvtColor(image,cv2.COLOR_BGR2HSV)
image_blur = cv2.medianBlur(image,9)

#Split in 64 tiles:
NUM_TILES_H = image.shape[1]/ SIZE_TILES
NUM_TILES_V = image.shape[0]/ SIZE_TILES

#Prepare the final image
final_image = np.zeros_like(image)
for i in range(NUM_TILES_H):
    for k in range(NUM_TILES_V):
        window = image_blur[SIZE_TILES*k:SIZE_TILES*(k+1),SIZE_TILES*i:SIZE_TILES*(i+1),:]
        #window_b = cv2.medianBlur(window,7)
        #cv2.imwrite(os.path.join(SAVE,'w_'+str(i)+'_'+str(k)+'.jpg'), window)
        median_v = np.median(window[:,:,2])
        median_s = np.median(window[:,:,1])
        final = np.zeros_like(window)
        final[(window[:,:,2] > median_v + THRES) ]= [1,1,1]
        final_image[SIZE_TILES*k:SIZE_TILES*(k+1),SIZE_TILES*i:SIZE_TILES*(i+1),:] = final


#Fix the final image
kernel = np.ones((3,3), np.uint8)

final_image = cv2.morphologyEx(final_image,cv2.MORPH_OPEN,kernel,iterations=12)

final_image = cv2.morphologyEx(final_image, cv2.MORPH_CLOSE, kernel, iterations=8)

final_image = cv2.medianBlur(final_image,9)
cv2.imwrite(os.path.join(SAVE,'mask.png'), final_image[:,:,0]*255)
masked_image = np.copy(image)
masked_image[final_image[:,:,0] == 0] = 0
cv2.imwrite(os.path.join(SAVE,'masked_image.jpg'), masked_image)

【讨论】:

  • 这是否回答了您自己的问题?如何?请详细说明——像这样的纯代码帖子通常对社区不是很有用。
猜你喜欢
  • 2021-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-02
  • 1970-01-01
  • 2013-07-25
  • 1970-01-01
  • 2020-01-06
相关资源
最近更新 更多