简体   繁体   English

如何使用OpenCV检测图像中的涟漪

[英]How to detect ripples in a image with OpenCV

So I have a picture of a sand dune that looks currently like this. 所以我有一张沙丘的照片,看起来像这样。 在此输入图像描述

What I'm trying to do is identify the ripples within the picture using opencv in Python. 我想要做的是使用Python中的opencv识别图片中的涟漪。 I'm just learning this library so I don't know all the quirks within the library. 我刚刚学习这个库,所以我不知道库里的所有怪癖。 I did some research, but couldn't find a problem similar to this one, this one is especially difficult because of the shadows that are created from the ripples. 我做了一些研究,但找不到与此类似的问题,由于涟漪产生的阴影,这个问题特别困难。 My expected outcome should be somewhat the inverse of this, making all the ripples standing out more than the other features. 我的预期结果应该与此相反,使得所有的涟漪都比其他特征更突出。 Below is a picture of a man with his hair as the feature that stands out. 下面是一张男人的照片,他的头发很突出。 I want to do the same thing with the ripples in the dune below. 我想对下面沙丘的涟漪做同样的事情。

图像在这里 The following code is what I have beneath and this is the output of my final product, but still needs some work. 下面的代码是我的下面代码,这是我最终产品的输出,但仍需要一些工作。

 path = "C:/some path//to get//to my picture//Dune field_resize.jpg"


# image I'm using
img = cv2.imread ( path , cv2.IMREAD_GRAYSCALE )
kernel = np.ones ( (5 , 5) , np.uint8 )

# Canny edge detecting
edges = cv2.Canny ( img , 75 , 200 )
th , img = cv2.threshold ( img , 220 , 255 , cv2.THRESH_BINARY_INV );

# Copy the thresholded image.
img_floodfill = img.copy ()

# Mask used to flood filling.
# Notice the size needs to be 2 pixels than the image.
h , w = img.shape[:2]
mask = np.zeros ( (h + 2 , w + 2) , np.uint8 )

# Floodfill from point (0, 0)
cv2.floodFill ( img_floodfill , mask , (0 , 0) , 255 );

# Invert floodfilled image
img_floodfill_inv = cv2.bitwise_not ( img_floodfill )

# Combine the two images to get the foreground.
img_out = img | img_floodfill_inv

# Display images.
cv2.imwrite ( "Thresholded Image.png" , img )
cv2.imwrite ( "Floodfilled Image.png" , img_floodfill )
cv2.imwrite ( "Inverted Floodfilled Image.png" , img_floodfill_inv )
cv2.imwrite ( "Foreground.png" , img )
cv2.waitKey ( 0 )

cv2.imwrite ( "canny_edge.png" , edges )

img_erosion = cv2.erode ( img , kernel , iterations=1 )

cv2.waitKey ( 0 )
cv2.destroyAllWindows ()

在这里输入图像

Here is a simple approach using some filtering 这是一种使用一些过滤的简单方法

  • Convert image to grayscale 将图像转换为灰度
  • Use canny edge detection to find edges 使用精确边缘检测来查找边缘
  • Find contours 查找轮廓
  • For each contour find its area and filter using a maximum threshold area 对于每个轮廓,使用最大阈值区域找到其面积和过滤器

Canny 谨慎的

在此输入图像描述

Detected ripples 检测到涟漪

在此输入图像描述

You may need to adjust the cv2.Canny or threshold area parameters. 您可能需要调整cv2.Canny或阈值区域参数。 Another possible approach to filtering after Canny detection would be to distinguish between straight and irregular lines . Canny检测后过滤的另一种可能方法是区分直线和不规则线 There are probably better filtering methods but this simple area approach gets most of the ripples. 可能有更好的过滤方法,但这种简单的区域方法可以获得大部分的涟漪。

import cv2
import numpy as np

original_image = cv2.imread('1.jpg')
gray = cv2.cvtColor(original_image, cv2.COLOR_BGR2GRAY)

canny = cv2.Canny(gray, 50, 150)
cnts = cv2.findContours(canny.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

threshold_max_area = 165
for c in cnts:
    area = cv2.contourArea(c)
    if area < threshold_max_area:
        cv2.drawContours(original_image,[c], 0, (0,255,0), 1)

cv2.imshow('canny', canny)
cv2.imshow('found', original_image)

cv2.waitKey(0)
cv2.destroyAllWindows()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM