if (mainColor == "orange") {
cv::Mat hsvImage;
cv::cvtColor(centerImage, hsvImage, cv::COLOR_BGR2HSV);
// 增强白纸背景检测(多条件组合)
cv::Mat paperMask1, paperMask2, paperMask;
// 条件1:高亮度区域(V > 220)
cv::inRange(hsvImage, cv::Scalar(0, 0, 220), cv::Scalar(180, 30, 255), paperMask1);
// 条件2:低饱和度区域(S < 25)
cv::inRange(hsvImage, cv::Scalar(0, 0, 0), cv::Scalar(180, 25, 255), paperMask2);
// 组合条件:高亮度OR低饱和度
cv::bitwise_or(paperMask1, paperMask2, paperMask);
// 形态学优化背景掩膜(去除纸上的小污点)
cv::Mat kernelBg = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(15, 15));
cv::morphologyEx(paperMask, paperMask, cv::MORPH_CLOSE, kernelBg);
// 创建精确的前景掩膜(反转+边缘优化)
cv::Mat foregroundMask = ~paperMask;
cv::Mat edges;
cv::Canny(centerImage, edges, 50, 150); // 边缘检测辅助
cv::bitwise_and(foregroundMask, edges, foregroundMask);
// 扩展橙色检测范围(适应不同光照)
std::vector<std::pair<cv::Scalar, cv::Scalar>> orangeRanges = {
{cv::Scalar(0, 100, 80), cv::Scalar(10, 255, 200)}, // 深橙色
{cv::Scalar(10, 80, 70), cv::Scalar(20, 255, 220)}, // 标准橙色
{cv::Scalar(20, 70, 60), cv::Scalar(25, 255, 200)}, // 浅橙色
{cv::Scalar(5, 40, 100), cv::Scalar(15, 100, 180)} // 阴影区域橙色
};
cv::Mat orangeMask = cv::Mat::zeros(hsvImage.size(), CV_8UC1);
for (const auto& range : orangeRanges) {
cv::Mat tempMask;
cv::inRange(hsvImage, range.first, range.second, tempMask);
cv::bitwise_or(orangeMask, tempMask, orangeMask);
}
// 结合前景掩膜(排除背景干扰)
cv::bitwise_and(orangeMask, foregroundMask, orangeMask);
// 动态形态学处理(基于图像分辨率)
int sizeFactor = centerImage.rows / 300;
cv::Mat kernelOpen = cv::getStructuringElement(
cv::MORPH_ELLIPSE, cv::Size(2*sizeFactor+1, 2*sizeFactor+1));
cv::morphologyEx(orangeMask, orangeMask, cv::MORPH_OPEN, kernelOpen);
cv::Mat kernelClose = cv::getStructuringElement(
cv::MORPH_ELLIPSE, cv::Size(6*sizeFactor+1, 6*sizeFactor+1));
cv::morphologyEx(orangeMask, orangeMask, cv::MORPH_CLOSE, kernelClose);
// 轮廓检测与筛选
std::vector<std::vector<cv::Point>> contours;
cv::findContours(orangeMask, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
std::vector<cv::Rect> orangeBoxes;
std::vector<std::string> ripenessLevels;
for (const auto& contour : contours) {
if (contour.size() < 5) continue;
double area = cv::contourArea(contour);
double perimeter = cv::arcLength(contour, true);
double circularity = 4 * CV_PI * area / (perimeter * perimeter + 1e-5);
cv::Rect bbox = cv::boundingRect(contour);
double aspectRatio = std::max(bbox.width, bbox.height) /
(std::min(bbox.width, bbox.height) + 1e-5);
// 凸性检测
std::vector<cv::Point> hull;
cv::convexHull(contour, hull);
double hullArea = cv::contourArea(hull);
double solidity = area / (hullArea + 1e-5);
// 形态特征验证(橙子)
if (area > 500 &&
circularity > 0.55 &&
aspectRatio < 1.6 &&
solidity > 0.82) {
// 创建精确的果实掩膜
cv::Mat fruitMask = cv::Mat::zeros(orangeMask.size(), CV_8UC1);
cv::drawContours(fruitMask, std::vector{contour}, -1, 255, cv::FILLED);
// 成熟度分析(ROI区域平均HSV)
cv::Scalar meanHSV = cv::mean(hsvImage, fruitMask);
// 成熟度分级(综合H,S,V)
std::string ripeness = "Semi-Ripe";
if (meanHSV[0] < 8 && meanHSV[1] < 100) ripeness = "Unripe";
else if (meanHSV[0] > 8 && meanHSV[0] < 15 && meanHSV[1] > 120) ripeness = "Ripe";
else if (meanHSV[0] >= 15 && meanHSV[1] > 130) ripeness = "Very Ripe";
else if (meanHSV[2] < 100) ripeness = "Underripe";
orangeBoxes.push_back(bbox);
ripenessLevels.push_back(ripeness);
}
}
// 结果标记
for (size_t i = 0; i < orangeBoxes.size(); i++) {
cv::Rect globalBox(orangeBoxes[i].x + centerRegion.x,
orangeBoxes[i].y + centerRegion.y,
orangeBoxes[i].width,
orangeBoxes[i].height);
// 根据成熟度设置标记颜色
cv::Scalar color;
if (ripenessLevels[i] == "Unripe") color = cv::Scalar(0, 255, 255); // 黄色
else if (ripenessLevels[i] == "Ripe") color = cv::Scalar(0, 165, 255); // 橙色
else color = cv::Scalar(0, 0, 255); // 红色
cv::rectangle(markedImage, globalBox, color, 2);
// 添加标签(避免重叠)
cv::Point textPos(globalBox.x, globalBox.y - 5);
if (globalBox.y < 30) textPos.y = globalBox.y + globalBox.height + 20;
cv::putText(markedImage, ripenessLevels[i] + " Orange",
textPos, cv::FONT_HERSHEY_SIMPLEX, 0.7, color, 2);
}
// 更新输出文件名
if (!orangeBoxes.empty()) {
outputName = shelfName + "_orange.jpg";
}
}检查错误