遍历目录图片,实现:
1.标识出图片的颜色,
2.蓝色边框标识出方格区域(10*10),
3.标识出油漆脱落的小方格数量(小正方形10%脱落,认为该区该小正方形整个脱落)占方格区域的数量(一般是100)比例和实际脱落面积比例(需扣除划痕面积)。
4.用文字在图片上标识出有脱落面积的比例。
2285657249@qq.com(可QQ交流)
注意:示例图片脱落不明显,可手动修改照片,以实现测试效果。
①10×10是小格数量,每个小格是2mm或1.5mm见方,面积不用真实值,用像素点也可以。②面漆的颜色大部分是黄色,有时是灰色(统一按黄色考虑)。底漆的颜色不一定是白色,大部分是灰色或红色。③可以考虑通过颜色的变化来进行脱落的识别。④补充一下比较明显脱落的照片。
这个单位是多少,比如10×10是毫米?
有几个疑问:
1、你这图片估计不是原图吧,现在宽是320像素,你所谓的10*10是按什么单位来计算的?
2、方格区域的数量(一般是100)是说要把图片分割成100个方格,然后去计算每个方格的脱落情况吗
3、实际脱落面积比例是说不考虑方格的问题,只考虑脱落区域(不规则)占整个图片的比例吗
这个不太会啊
这个有意思,但是有些地方不够完善,掉漆的位置一定是白色的吗?如果里面有底漆,导致掉漆呈现红色,或者照片里反光,都是会误识别的,这个怎么算
你说的10乘以10的小方格是像素吗,还是有其它单位?漆脱落的小方格数量占方格区域的数量为什么一般是100?不太明白。
标王啊,看来要学一下OpenCV了
识别油漆脱落点,还要判断不是反光的地方,有点儿难哦。
opencv库应该可以跑,不过朋友的硬件是打算用什么?openmv还是树莓派官方摄像头还是OV7725
这个单位是多少
使用cv处理,hsv颜色识别,然后框选出脱落的面积,使用are算子提取,即可。
像素和实面积是多少啊还是自己假设啊,如果是摄像机要考虑,不同拍摄角度距离,后不同的比例
对于这个问题,色彩分水岭似乎是一个很好的方法.
当你解决这个问题时,定义标记的前景和背景是困难的部分!
建议使用形态梯度沿着破坏面积获得良好的边缘。
第一步:
import numpy as np
import cv2
img = cv2.imread('image.png')
blur = cv2.GaussianBlur(img, (7, 7), 2)
h, w = img.shape[:2]
# Morphological gradient
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7, 7))
gradient = cv2.morphologyEx(blur, cv2.MORPH_GRADIENT, kernel)
cv2.imshow('Morphological gradient', gradient)
cv2.waitKey()
第二步:使用一些阈值来对梯度进行二值化
lowerb = np.array([0, 0, 0])
upperb = np.array([15, 15, 15])
binary = cv2.inRange(gradient, lowerb, upperb)
cv2.imshow('Binarized gradient', binary)
cv2.waitKey()
第三步:遍历边缘上的像素并使用floodFill()从二进制图像中删除多余部分
for row in range(h):
if binary[row, 0] == 255:
cv2.floodFill(binary, None, (0, row), 0)
if binary[row, w-1] == 255:
cv2.floodFill(binary, None, (w-1, row), 0)
for col in range(w):
if binary[0, col] == 255:
cv2.floodFill(binary, None, (col, 0), 0)
if binary[h-1, col] == 255:
cv2.floodFill(binary, None, (col, h-1), 0)
cv2.imshow('Filled binary gradient', binary)
cv2.waitKey()
第四步:清理
foreground = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel)
foreground = cv2.morphologyEx(foreground, cv2.MORPH_CLOSE, kernel)
cv2.imshow('Cleanup up crystal foreground mask', foreground)
cv2.waitKey()
第五步:获得被破坏图像
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (17, 17))
background = cv2.dilate(foreground, kernel, iterations=3)
unknown = cv2.subtract(background, foreground)
cv2.imshow('Background', background)
cv2.waitKey()
第六步:标记分界线
markers = cv2.connectedComponents(foreground)[1]
markers += 1 # Add one to all labels so that background is 1, not 0
markers[unknown==255] = 0 # mark the region of unknown with zero
markers = cv2.watershed(img, markers)
第七步:标记块
hue_markers = np.uint8(179*np.float32(markers)/np.max(markers))
blank_channel = 255*np.ones((h, w), dtype=np.uint8)
marker_img = cv2.merge([hue_markers, blank_channel, blank_channel])
marker_img = cv2.cvtColor(marker_img, cv2.COLOR_HSV2BGR)
cv2.imshow('Colored markers', marker_img)
cv2.waitKey()
第八步:与原始图像对比
labeled_img = img.copy()
labeled_img[markers>1] = marker_img[markers>1] # 1 is background color
labeled_img = cv2.addWeighted(img, 0.5, labeled_img, 0.5, 0)
cv2.imshow('watershed_result.png', labeled_img)
cv2.waitKey()
最后:计算面积
.
import math
class Round(): #圆形
def __init__(self, R):
self.R = R
def area(self):
return self.R * self.R * 3.14
def girth(self):
return self.R * 2 * 3.14
class Rectangle():#矩形
def __init__(self, length, width):
self.length = length
self.width = width
def area(self):
return self.length * self.width
def girth(self):
return self.length + self.width
class Triangle():#三角形
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def area(self):
l = (self.a + self.b + self.c)/2
return round(math.sqrt(l * (l - self.a) * (l - self.b) * (l - self.c)), 2) #round保留2为小数
def girth(self):
return self.a + self.c + self.c
class Guadrilateral():#任意四边形
def __init__(self, a, b, c, d, angle):
self.a = a
self.b = b
self.c = c
self.d = d
self.angle = angle
def area(self):
l = (self.a + self.b + self.c + self.d)/2
return round(math.sqrt((l - self.a) * (l - self.b) * (l - self.c) * (l - self.d) -
self.a * self.b * self.c * self.d
* math.pow(math.cos(math.radians(self.angle)), 2)), 2) #pow函数幂次方radians弧度转换为角度
def girth(self):
return self.a + self.b + self.c + self.d
print("----图形计算工具----")
print("*******************")
print("***你可以选择的图形***")
print("********圆形********")
print("********矩形********")
print("*******三角形********")
print("*****任意四边形*******")
target = str(input("请输入你想要计算图形的名称"))
if target == "圆形":
x1 = int(input("请输入半径(厘米):"))
print("圆形的面积为:" + str(Round(x1).area()) + "(平方厘米)!")
print("圆形的周长为:" + str(Round(x1).girth()) + "(厘米)!")
elif target == "矩形":
x1 = int(input("请输入长度(厘米):"))
x2 = int(input("请输入宽度(厘米):"))
print("矩形的面积为:" + str(Rectangle(x1, x2).area()) + "(平方厘米)!")
print("矩形的周长为:" + str(Rectangle(x1, x2).girth()) + "(厘米)!")
elif target == "三角形":
x1 = int(input("请输入边a(厘米):"))
x2 = int(input("请输入边b(厘米):"))
x3 = int(input("请输入边c(厘米):"))
print("三角形的面积为:" + str(Triangle(x1, x2, x3).area()) + "(平方厘米)!")
print("三角形的周长为:" + str(Triangle(x1, x2, x3).girth()) + "(厘米)!")
elif target == "任意四边形":
x1 = int(input("请输入边a(厘米):"))
x2 = int(input("请输入边b(厘米):"))
x3 = int(input("请输入边c(厘米):"))
x4 = int(input("请输入边d(厘米):"))
x5 = int(input("请输入邻对角角度和的一半(°):"))
print("三角形的面积为:" + str(Guadrilateral(x1, x2, x3, x4, x5).area()) + "(平方厘米)!")
print("三角形的周长为:" + str(Guadrilateral(x1, x2, x3, x4, x5).girth()) + "(厘米)!")