mirror of
https://github.com/NanjingForestryUniversity/supermachine--tomato-passion_fruit.git
synced 2025-11-08 22:34:00 +00:00
feat:新增百香果绿色占比计算;tg文件夹下为百香果绿色占比各个结果图实验程序
This commit is contained in:
parent
7c191d9d42
commit
68fd790823
@ -317,6 +317,40 @@ class Passion_fruit:
|
||||
return np.zeros_like(rgb_img)
|
||||
return result
|
||||
|
||||
def extract_green_pixels_cv(self,image):
|
||||
'''
|
||||
提取图像中的绿色像素。
|
||||
:param image:
|
||||
:return:
|
||||
'''
|
||||
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
||||
# Define the HSV range for green
|
||||
lower_green = np.array([setting.low_H, setting.low_S, setting.low_V])
|
||||
upper_green = np.array([setting.high_H, setting.high_S, setting.high_V])
|
||||
# Convert the image to HSV
|
||||
hsv = cv2.cvtColor(image_rgb, cv2.COLOR_RGB2HSV)
|
||||
# Create the mask
|
||||
mask = cv2.inRange(hsv, lower_green, upper_green)
|
||||
# Bitwise-AND mask and original image
|
||||
res = cv2.bitwise_and(image_rgb, image_rgb, mask=mask)
|
||||
# Convert result to BGR for display
|
||||
res_bgr = cv2.cvtColor(res, cv2.COLOR_RGB2BGR)
|
||||
return mask
|
||||
|
||||
def pixel_comparison(self, defect, mask):
|
||||
'''
|
||||
比较两幅图像的像素值,如果相同则赋值为0,不同则赋值为255。
|
||||
:param defect:
|
||||
:param mask:
|
||||
:return:
|
||||
'''
|
||||
# 确保图像是二值图像
|
||||
_, defect_binary = cv2.threshold(defect, 127, 255, cv2.THRESH_BINARY)
|
||||
_, mask_binary = cv2.threshold(mask, 127, 255, cv2.THRESH_BINARY)
|
||||
# 执行像素比较
|
||||
green_img = np.where(defect_binary == mask_binary, 0, 255).astype(np.uint8)
|
||||
return green_img
|
||||
|
||||
#糖度预测模型
|
||||
class Spec_predict(object):
|
||||
def __init__(self, load_from=None, debug_mode=False):
|
||||
@ -390,35 +424,28 @@ class Data_processing:
|
||||
return np.zeros_like(image_array) if image_array is not None else np.zeros((100, 100), dtype=np.uint8)
|
||||
# 应用中值滤波
|
||||
image_filtered = cv2.medianBlur(image_array, 5)
|
||||
|
||||
# 形态学闭操作
|
||||
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (15, 15))
|
||||
image_closed = cv2.morphologyEx(image_filtered, cv2.MORPH_CLOSE, kernel)
|
||||
|
||||
# 查找轮廓
|
||||
contours, _ = cv2.findContours(image_closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
||||
|
||||
# 创建空白图像以绘制轮廓
|
||||
image_contours = np.zeros_like(image_array)
|
||||
|
||||
# 进行多边形拟合并填充轮廓
|
||||
for contour in contours:
|
||||
epsilon = 0.001 * cv2.arcLength(contour, True)
|
||||
approx = cv2.approxPolyDP(contour, epsilon, True)
|
||||
if cv2.contourArea(approx) > 100: # 仅处理较大的轮廓
|
||||
cv2.drawContours(image_contours, [approx], -1, (255, 255, 255), -1)
|
||||
|
||||
return image_contours
|
||||
|
||||
def analyze_ellipse(self, image_array):
|
||||
# 查找白色区域的轮廓
|
||||
_, binary_image = cv2.threshold(image_array, 127, 255, cv2.THRESH_BINARY)
|
||||
contours, _ = cv2.findContours(binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
||||
|
||||
# 初始化变量用于存储最大轮廓的长径和短径
|
||||
major_axis = 0
|
||||
minor_axis = 0
|
||||
|
||||
# 对每个找到的轮廓,找出可以包围它的最小椭圆,并计算长径和短径
|
||||
for contour in contours:
|
||||
if len(contour) >= 5: # 至少需要5个点来拟合椭圆
|
||||
@ -586,10 +613,13 @@ class Data_processing:
|
||||
combined_mask = pf.create_mask(hsv_image)
|
||||
combined_mask = pf.apply_morphology(combined_mask)
|
||||
max_mask = pf.find_largest_component(combined_mask)
|
||||
|
||||
filled_img, defect = self.fill_holes(max_mask)
|
||||
|
||||
contour_mask = self.contour_process(max_mask)
|
||||
fore = pf.bitwise_and_rgb_with_binary(img, contour_mask)
|
||||
mask = pf.extract_green_pixels_cv(fore)
|
||||
green_img = pf.pixel_comparison(defect, mask)
|
||||
green_percentage = np.sum(green_img == 255) / np.sum(contour_mask == 255)
|
||||
green_percentage = round(green_percentage, 2)
|
||||
long_axis, short_axis = self.analyze_ellipse(contour_mask)
|
||||
#重量单位为g,加上了一点随机数
|
||||
weight_real = self.weight_estimates(long_axis, short_axis)
|
||||
@ -608,12 +638,13 @@ class Data_processing:
|
||||
# print(f'直径:{diameter}')
|
||||
if diameter < 2.5:
|
||||
diameter = 0
|
||||
green_percentage = 0
|
||||
weight = 0
|
||||
number_defects = 0
|
||||
total_pixels = 0
|
||||
rp = cv2.cvtColor(np.ones((setting.n_rgb_rows, setting.n_rgb_cols, setting.n_rgb_bands),
|
||||
dtype=np.uint8), cv2.COLOR_BGR2RGB)
|
||||
return diameter, weight, number_defects, total_pixels, rp
|
||||
return diameter, green_percentage, weight, number_defects, total_pixels, rp
|
||||
|
||||
def process_data(seif, cmd: str, images: list, spec: any, pipe: Pipe, detector: Spec_predict) -> bool:
|
||||
"""
|
||||
@ -644,7 +675,7 @@ class Data_processing:
|
||||
|
||||
elif cmd == 'PF':
|
||||
# 百香果
|
||||
diameter, weight, number_defects, total_pixels, rp = seif.analyze_passion_fruit(img)
|
||||
diameter, green_percentage, weight, number_defects, total_pixels, rp = seif.analyze_passion_fruit(img)
|
||||
if i <= 2:
|
||||
diameter_axis_list.append(diameter)
|
||||
max_defect_num = max(max_defect_num, number_defects)
|
||||
@ -652,6 +683,7 @@ class Data_processing:
|
||||
if i == 1:
|
||||
rp_result = rp
|
||||
weight = weight
|
||||
gp = round(green_percentage, 2)
|
||||
|
||||
else:
|
||||
logging.error(f'错误指令,指令为{cmd}')
|
||||
@ -668,14 +700,12 @@ class Data_processing:
|
||||
defect_num=max_defect_num, total_defect_area=max_total_defect_area, rp=rp_result)
|
||||
return response
|
||||
elif cmd == 'PF':
|
||||
green_percentage = 0
|
||||
brix = detector.predict(spec)
|
||||
if diameter == 0:
|
||||
brix = 0
|
||||
# print(f'预测的brix值为:{brix}; 预测的直径为:{diameter}; 预测的重量为:{weight}; 预测的绿色比例为:{green_percentage};'
|
||||
# f' 预测的缺陷数量为:{max_defect_num}; 预测的总缺陷面积为:{max_total_defect_area};')
|
||||
response = pipe.send_data(cmd=cmd, brix=brix, green_percentage=green_percentage, diameter=diameter,
|
||||
weight=weight,
|
||||
response = pipe.send_data(cmd=cmd, brix=brix, green_percentage=gp, diameter=diameter, weight=weight,
|
||||
defect_num=max_defect_num, total_defect_area=max_total_defect_area, rp=rp_result)
|
||||
return response
|
||||
|
||||
|
||||
@ -32,6 +32,14 @@ class Config:
|
||||
value_target = 25
|
||||
value_delta = 10
|
||||
|
||||
#提取绿色像素参数
|
||||
low_H = 0
|
||||
low_S = 100
|
||||
low_V = 0
|
||||
high_H = 60
|
||||
high_S = 180
|
||||
high_V = 60
|
||||
|
||||
#spec_predict
|
||||
#筛选谱段并未使用,在qt取数据时已经筛选
|
||||
selected_bands = [8, 9, 10, 48, 49, 50, 77, 80, 103, 108, 115, 143, 145]
|
||||
|
||||
53
20240529RGBtest3/tg/config.py
Normal file
53
20240529RGBtest3/tg/config.py
Normal file
@ -0,0 +1,53 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Time : 2024/6/17 下午3:36
|
||||
# @Author : TG
|
||||
# @File : config.py
|
||||
# @Software: PyCharm
|
||||
|
||||
from root_dir import ROOT_DIR
|
||||
|
||||
class Config:
|
||||
#文件相关参数
|
||||
#预热参数
|
||||
n_spec_rows, n_spec_cols, n_spec_bands = 25, 30, 13
|
||||
n_rgb_rows, n_rgb_cols, n_rgb_bands = 613, 800, 3
|
||||
tomato_img_dir = ROOT_DIR / 'models' / 'TO.bmp'
|
||||
passion_fruit_img_dir = ROOT_DIR / 'models' / 'PF.bmp'
|
||||
#模型路径
|
||||
#糖度模型
|
||||
brix_model_path = ROOT_DIR / 'models' / 'passion_fruit.joblib'
|
||||
#图像分类模型
|
||||
imgclassifier_model_path = ROOT_DIR / 'models' / 'imgclassifier.joblib'
|
||||
imgclassifier_class_indices_path = ROOT_DIR / 'models' / 'class_indices.json'
|
||||
|
||||
|
||||
#classifer.py参数
|
||||
#tomato
|
||||
find_reflection_threshold = 190
|
||||
extract_g_r_factor = 1.5
|
||||
|
||||
#passion_fruit
|
||||
hue_value = 37
|
||||
hue_delta = 10
|
||||
value_target = 25
|
||||
value_delta = 10
|
||||
|
||||
#spec_predict
|
||||
#筛选谱段并未使用,在qt取数据时已经筛选
|
||||
selected_bands = [8, 9, 10, 48, 49, 50, 77, 80, 103, 108, 115, 143, 145]
|
||||
|
||||
#data_processing
|
||||
#根据标定数据计算的参数,实际长度/像素长度,单位cm
|
||||
pixel_length_ratio = 6.3/425
|
||||
#绿叶面积阈值,高于此阈值认为连通域是绿叶
|
||||
area_threshold = 20000
|
||||
#百香果密度(g/cm^3)
|
||||
density = 0.652228972
|
||||
#百香果面积比例,每个像素代表的实际面积(cm^2)
|
||||
area_ratio = 0.00021973702422145334
|
||||
|
||||
#def analyze_tomato
|
||||
#s_l通道阈值
|
||||
threshold_s_l = 180
|
||||
threshold_fore_g_r_t = 20
|
||||
|
||||
256
20240529RGBtest3/tg/passion_fruit_rgb.py
Normal file
256
20240529RGBtest3/tg/passion_fruit_rgb.py
Normal file
@ -0,0 +1,256 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Time : 2024/6/26 下午5:31
|
||||
# @Author : TG
|
||||
# @File : passion_fruit_rgb.py
|
||||
# @Software: PyCharm
|
||||
import os
|
||||
import cv2
|
||||
import numpy as np
|
||||
import argparse
|
||||
import logging
|
||||
from config import Config as setting
|
||||
|
||||
class Passion_fruit:
|
||||
def __init__(self, hue_value=setting.hue_value, hue_delta=setting.hue_delta,
|
||||
value_target=setting.value_target, value_delta=setting.value_delta):
|
||||
# 初始化常用参数
|
||||
self.hue_value = hue_value
|
||||
self.hue_delta = hue_delta
|
||||
self.value_target = value_target
|
||||
self.value_delta = value_delta
|
||||
|
||||
def create_mask(self, hsv_image):
|
||||
# 创建H通道阈值掩码
|
||||
lower_hue = np.array([self.hue_value - self.hue_delta, 0, 0])
|
||||
upper_hue = np.array([self.hue_value + self.hue_delta, 255, 255])
|
||||
hue_mask = cv2.inRange(hsv_image, lower_hue, upper_hue)
|
||||
# 创建V通道排除中心值的掩码
|
||||
lower_value_1 = np.array([0, 0, 0])
|
||||
upper_value_1 = np.array([180, 255, self.value_target - self.value_delta])
|
||||
lower_value_2 = np.array([0, 0, self.value_target + self.value_delta])
|
||||
upper_value_2 = np.array([180, 255, 255])
|
||||
value_mask_1 = cv2.inRange(hsv_image, lower_value_1, upper_value_1)
|
||||
value_mask_1 = cv2.bitwise_not(value_mask_1)
|
||||
value_mask_2 = cv2.inRange(hsv_image, lower_value_2, upper_value_2)
|
||||
value_mask = cv2.bitwise_and(value_mask_1, value_mask_2)
|
||||
|
||||
# 合并H通道和V通道掩码
|
||||
return cv2.bitwise_and(hue_mask, value_mask)
|
||||
|
||||
def apply_morphology(self, mask):
|
||||
# 应用形态学操作
|
||||
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
|
||||
return cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
|
||||
|
||||
def find_largest_component(self, mask):
|
||||
if mask is None or mask.size == 0 or np.all(mask == 0):
|
||||
logging.warning("RGB 图像为空或全黑,返回一个全黑RGB图像。")
|
||||
return np.zeros((setting.n_rgb_rows, setting.n_rgb_cols, setting.n_rgb_bands), dtype=np.uint8) \
|
||||
if mask is None else np.zeros_like(mask)
|
||||
# 寻找最大连通组件
|
||||
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(mask, 4, cv2.CV_32S)
|
||||
if num_labels < 2:
|
||||
return None # 没有找到显著的组件
|
||||
max_label = 1 + np.argmax(stats[1:, cv2.CC_STAT_AREA]) # 跳过背景
|
||||
return (labels == max_label).astype(np.uint8) * 255
|
||||
def draw_contours_on_image(self, original_image, mask_image):
|
||||
"""
|
||||
在原图上绘制轮廓
|
||||
:param original_image: 原图的NumPy数组
|
||||
:param mask_image: 轮廓mask的NumPy数组
|
||||
:return: 在原图上绘制轮廓后的图像
|
||||
"""
|
||||
# 确保mask_image是二值图像
|
||||
_, binary_mask = cv2.threshold(mask_image, 127, 255, cv2.THRESH_BINARY)
|
||||
# 查找mask图像中的轮廓
|
||||
contours, _ = cv2.findContours(binary_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
||||
# 在原图上绘制轮廓
|
||||
cv2.drawContours(original_image, contours, -1, (0, 255, 0), 2)
|
||||
return original_image
|
||||
|
||||
def bitwise_and_rgb_with_binary(self, rgb_img, bin_img):
|
||||
'''
|
||||
将 RGB 图像与二值图像进行按位与操作,用于将二值区域应用于原始图像。
|
||||
:param rgb_img: 原始 RGB 图像
|
||||
:param bin_img: 二值图像
|
||||
:return: 按位与后的结果图像
|
||||
'''
|
||||
# 检查 RGB 图像是否为空或全黑
|
||||
if rgb_img is None or rgb_img.size == 0 or np.all(rgb_img == 0):
|
||||
logging.warning("RGB 图像为空或全黑,返回一个全黑RGB图像。")
|
||||
return np.zeros((setting.n_rgb_rows, setting.n_rgb_cols, setting.n_rgb_bands), dtype=np.uint8) \
|
||||
if rgb_img is None else np.zeros_like(rgb_img)
|
||||
# 检查二值图像是否为空或全黑
|
||||
if bin_img is None or bin_img.size == 0 or np.all(bin_img == 0):
|
||||
logging.warning("二值图像为空或全黑,返回一个全黑RGB图像。")
|
||||
return np.zeros((setting.n_rgb_rows, setting.n_rgb_cols, setting.n_rgb_bands), dtype=np.uint8) \
|
||||
if bin_img is None else np.zeros_like(bin_img)
|
||||
# 转换二值图像为三通道
|
||||
try:
|
||||
bin_img_3channel = cv2.cvtColor(bin_img, cv2.COLOR_GRAY2BGR)
|
||||
except cv2.error as e:
|
||||
logging.error(f"转换二值图像时发生错误: {e}")
|
||||
return np.zeros_like(rgb_img)
|
||||
# 进行按位与操作
|
||||
try:
|
||||
result = cv2.bitwise_and(rgb_img, bin_img_3channel)
|
||||
except cv2.error as e:
|
||||
logging.error(f"执行按位与操作时发生错误: {e}")
|
||||
return np.zeros_like(rgb_img)
|
||||
return result
|
||||
|
||||
|
||||
|
||||
def fill_holes(bin_img):
|
||||
|
||||
img_filled = bin_img.copy()
|
||||
height, width = bin_img.shape
|
||||
mask = np.zeros((height + 2, width + 2), np.uint8)
|
||||
cv2.floodFill(img_filled, mask, (0, 0), 255)
|
||||
img_filled_inv = cv2.bitwise_not(img_filled)
|
||||
img_filled = cv2.bitwise_or(bin_img, img_filled)
|
||||
img_defect = img_filled_inv[:height, :width]
|
||||
return img_filled, img_defect
|
||||
|
||||
def contour_process(image_array):
|
||||
# 检查图像是否为空或全黑
|
||||
if image_array is None or image_array.size == 0 or np.all(image_array == 0):
|
||||
logging.warning("输入的图像为空或全黑,返回一个全黑图像。")
|
||||
return np.zeros_like(image_array) if image_array is not None else np.zeros((100, 100), dtype=np.uint8)
|
||||
# 应用中值滤波
|
||||
image_filtered = cv2.medianBlur(image_array, 5)
|
||||
# 形态学闭操作
|
||||
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (15, 15))
|
||||
image_closed = cv2.morphologyEx(image_filtered, cv2.MORPH_CLOSE, kernel)
|
||||
# 查找轮廓
|
||||
contours, _ = cv2.findContours(image_closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
||||
# 创建空白图像以绘制轮廓
|
||||
image_contours = np.zeros_like(image_array)
|
||||
# 进行多边形拟合并填充轮廓
|
||||
for contour in contours:
|
||||
epsilon = 0.001 * cv2.arcLength(contour, True)
|
||||
approx = cv2.approxPolyDP(contour, epsilon, True)
|
||||
if cv2.contourArea(approx) > 100: # 仅处理较大的轮廓
|
||||
cv2.drawContours(image_contours, [approx], -1, (255, 255, 255), -1)
|
||||
|
||||
return image_contours
|
||||
|
||||
|
||||
def extract_green_pixels_cv(image):
|
||||
"""
|
||||
使用 OpenCV 提取图像中的绿色像素,并可选择保存结果图像。
|
||||
|
||||
参数:
|
||||
image_path (str): 输入图像的文件路径。
|
||||
save_path (str, optional): 输出图像的保存路径,若提供此参数,则保存提取的绿色像素图像。
|
||||
|
||||
返回:
|
||||
输出图像,绿色像素为白色,其他像素为黑色。
|
||||
"""
|
||||
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
||||
# Define the HSV range for green
|
||||
lower_green = np.array([0, 100, 0])
|
||||
upper_green = np.array([60, 180, 60])
|
||||
# Convert the image to HSV
|
||||
hsv = cv2.cvtColor(image_rgb, cv2.COLOR_RGB2HSV)
|
||||
# Create the mask
|
||||
mask = cv2.inRange(hsv, lower_green, upper_green)
|
||||
# Bitwise-AND mask and original image
|
||||
res = cv2.bitwise_and(image_rgb, image_rgb, mask=mask)
|
||||
# Convert result to BGR for display
|
||||
res_bgr = cv2.cvtColor(res, cv2.COLOR_RGB2BGR)
|
||||
return mask
|
||||
|
||||
|
||||
def pixel_comparison(defect, mask):
|
||||
"""
|
||||
比较两幅图像的像素值,如果相同则赋值为0,不同则赋值为255。
|
||||
参数:
|
||||
defect_path (str): 第一幅图像的路径。
|
||||
mask_path (str): 第二幅图像的路径。
|
||||
save_path (str, optional): 结果图像的保存路径。
|
||||
返回:
|
||||
numpy.ndarray: 处理后的图像数组。
|
||||
"""
|
||||
# 确保图像是二值图像
|
||||
_, defect_binary = cv2.threshold(defect, 127, 255, cv2.THRESH_BINARY)
|
||||
_, mask_binary = cv2.threshold(mask, 127, 255, cv2.THRESH_BINARY)
|
||||
# 执行像素比较
|
||||
green_img = np.where(defect_binary == mask_binary, 0, 255).astype(np.uint8)
|
||||
return green_img
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Process some integers.')
|
||||
parser.add_argument('--dir_path', type=str,
|
||||
default=r'D:\project\supermachine--tomato-passion_fruit\20240529RGBtest3\tg\test',
|
||||
help='the directory path of images')
|
||||
parser.add_argument('--threshold_s_l', type=int, default=180,
|
||||
help='the threshold for s_l')
|
||||
parser.add_argument('--threshold_r_b', type=int, default=15,
|
||||
help='the threshold for r_b')
|
||||
|
||||
args = parser.parse_args()
|
||||
pf = Passion_fruit()
|
||||
|
||||
for img_file in os.listdir(args.dir_path):
|
||||
if img_file.endswith('.bmp'):
|
||||
img_path = os.path.join(args.dir_path, img_file)
|
||||
img = cv2.imread(img_path)
|
||||
cv2.imshow('img', img)
|
||||
hsv_image = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
|
||||
cv2.imshow('hsv', hsv_image)
|
||||
combined_mask = pf.create_mask(hsv_image)
|
||||
cv2.imshow('combined_mask1', combined_mask)
|
||||
combined_mask = pf.apply_morphology(combined_mask)
|
||||
cv2.imshow('combined_mask2', combined_mask)
|
||||
max_mask = pf.find_largest_component(combined_mask)
|
||||
cv2.imshow('max_mask', max_mask)
|
||||
|
||||
filled_img, defect = fill_holes(max_mask)
|
||||
cv2.imshow('filled_img', filled_img)
|
||||
cv2.imshow('defect', defect)
|
||||
|
||||
contour_mask = contour_process(max_mask)
|
||||
cv2.imshow('contour_mask', contour_mask)
|
||||
|
||||
fore = pf.bitwise_and_rgb_with_binary(img, contour_mask)
|
||||
cv2.imshow('fore', fore)
|
||||
|
||||
mask = extract_green_pixels_cv(fore)
|
||||
cv2.imshow('mask', mask)
|
||||
|
||||
green_img = pixel_comparison(defect, mask)
|
||||
cv2.imshow('green_img', green_img)
|
||||
|
||||
green_percentage = np.sum(green_img == 255) / np.sum(contour_mask == 255)
|
||||
green_percentage = round(green_percentage, 2)
|
||||
|
||||
print(np.sum(green_img == 255))
|
||||
print(np.sum(contour_mask == 255))
|
||||
print(green_percentage)
|
||||
|
||||
|
||||
|
||||
|
||||
edge = pf.draw_contours_on_image(img, contour_mask)
|
||||
cv2.imshow('edge', edge)
|
||||
org_defect = pf.bitwise_and_rgb_with_binary(edge, max_mask)
|
||||
cv2.imshow('org_defect', org_defect)
|
||||
|
||||
|
||||
cv2.waitKey(0)
|
||||
cv2.destroyAllWindows()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
61
20240529RGBtest3/tg/t.py
Normal file
61
20240529RGBtest3/tg/t.py
Normal file
@ -0,0 +1,61 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Time : 2024/6/26 下午6:15
|
||||
# @Author : TG
|
||||
# @File : t.py
|
||||
# @Software: PyCharm
|
||||
import cv2
|
||||
import numpy as np
|
||||
|
||||
|
||||
def nothing(x):
|
||||
pass
|
||||
|
||||
|
||||
# Create a window
|
||||
cv2.namedWindow('Green Pixels Selector')
|
||||
|
||||
# Create trackbars for color change
|
||||
cv2.createTrackbar('Lower Hue', 'Green Pixels Selector', 0, 255, nothing)
|
||||
cv2.createTrackbar('Lower Sat', 'Green Pixels Selector', 100, 255, nothing)
|
||||
cv2.createTrackbar('Lower Val', 'Green Pixels Selector', 0, 255, nothing)
|
||||
cv2.createTrackbar('Upper Hue', 'Green Pixels Selector', 60, 255, nothing)
|
||||
cv2.createTrackbar('Upper Sat', 'Green Pixels Selector', 180, 255, nothing)
|
||||
cv2.createTrackbar('Upper Val', 'Green Pixels Selector', 60, 255, nothing)
|
||||
|
||||
# Load image
|
||||
image = cv2.imread(r'D:\project\supermachine--tomato-passion_fruit\20240529RGBtest3\tg\test\23.bmp')
|
||||
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
||||
|
||||
while (True):
|
||||
# Get current positions of the trackbars
|
||||
lh = cv2.getTrackbarPos('Lower Hue', 'Green Pixels Selector')
|
||||
ls = cv2.getTrackbarPos('Lower Sat', 'Green Pixels Selector')
|
||||
lv = cv2.getTrackbarPos('Lower Val', 'Green Pixels Selector')
|
||||
uh = cv2.getTrackbarPos('Upper Hue', 'Green Pixels Selector')
|
||||
us = cv2.getTrackbarPos('Upper Sat', 'Green Pixels Selector')
|
||||
uv = cv2.getTrackbarPos('Upper Val', 'Green Pixels Selector')
|
||||
|
||||
# Define the HSV range for green
|
||||
lower_green = np.array([lh, ls, lv])
|
||||
upper_green = np.array([uh, us, uv])
|
||||
|
||||
# Convert the image to HSV
|
||||
hsv = cv2.cvtColor(image_rgb, cv2.COLOR_RGB2HSV)
|
||||
|
||||
# Create the mask
|
||||
mask = cv2.inRange(hsv, lower_green, upper_green)
|
||||
|
||||
# Bitwise-AND mask and original image
|
||||
res = cv2.bitwise_and(image_rgb, image_rgb, mask=mask)
|
||||
|
||||
# Convert result to BGR for display
|
||||
res_bgr = cv2.cvtColor(res, cv2.COLOR_RGB2BGR)
|
||||
|
||||
# Display the resulting frame
|
||||
cv2.imshow('Green Pixels Selector', res_bgr)
|
||||
|
||||
if cv2.waitKey(1) & 0xFF == ord('q'):
|
||||
break
|
||||
|
||||
# When everything done, release the window
|
||||
cv2.destroyAllWindows()
|
||||
@ -209,8 +209,7 @@ class Pipe:
|
||||
defect_num + total_defect_area + height + width + img_bytes)
|
||||
elif cmd == 'PF':
|
||||
brix = int(brix * 1000).to_bytes(2, byteorder='big')
|
||||
gp = 0
|
||||
gp = gp.to_bytes(1, byteorder='big')
|
||||
gp = int(green_percentage * 100).to_bytes(1, byteorder='big')
|
||||
weight = weight.to_bytes(1, byteorder='big')
|
||||
send_message = (length + cmd_re + brix + gp + diameter + weight +
|
||||
defect_num + total_defect_area + height + width + img_bytes)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user