Reputation: 21
I'm working on an object detection project in C++ using OpenCV. Specifically, I capture an image (e.g., coins on a background) and then try to detect them via Canny edge detection and contour filtering. However, I struggle with getting consistent results under different lighting conditions. I have tried:
This is an example: Original: Original
After preprocessing: After preprocessing:
After Canny: After Canny
I use the following functions to prepare the image and detect edges. I've tried to build an “all-in-one” pipeline that includes sharpening, brightness/contrast adjustments, blur, either auto or manual Canny, optional dilation, and a final morphological operation.
Even though I can tune the parameters for one scenario, results often vary significantly when lighting changes slightly or the objects move. Sometimes edges look fine, other times they're broken or noisy.
A shortened version of my function:
void ObjectFinder::applyEdgeFilter(const cv::Mat& input, cv::Mat& preCanny, cv::Mat& edgeImage) const {
cv::Mat gray;
cv::cvtColor(input, gray, cv::COLOR_BGR2GRAY);
cv::equalizeHist(gray, gray);
cv::Mat sharpened;
if (m_sharpenMode == 1) {
cv::Mat blurredForSharpen;
cv::GaussianBlur(gray, blurredForSharpen, cv::Size(0, 0), 3);
double factor = (m_sharpenStrength / 100.0) - 1.0;
cv::addWeighted(gray, 1 + factor, blurredForSharpen, -factor, 0, sharpened);
} else if (m_sharpenMode == 2) {
cv::medianBlur(gray, sharpened, 3);
} else {
sharpened = gray.clone();
}
double alpha = m_contrastValue / 100.0;
int beta = m_brightnessValue - 100;
cv::Mat brightContrastAdjusted;
sharpened.convertTo(brightContrastAdjusted, -1, alpha, beta);
double sigmaBlur = (m_blurSigmaValue == 0) ? 0.1 : m_blurSigmaValue / 10.0;
cv::GaussianBlur(brightContrastAdjusted, preCanny, cv::Size(0, 0), sigmaBlur, sigmaBlur);
if (m_autoCannyMode == 1) {
double med = computeMedian(preCanny);
double sigmaAuto = m_sigmaValue / 100.0;
int lower = std::max(0, int((1.0 - sigmaAuto) * med));
int upper = std::min(255, int((1.0 + sigmaAuto) * med));
cv::Canny(preCanny, edgeImage, lower, upper);
} else {
cv::Canny(preCanny, edgeImage, m_lowThreshold, m_highThreshold);
}
if (m_showDilation == 1) {
cv::dilate(edgeImage, edgeImage, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)));
}
cv::Mat morphKernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5));
cv::morphologyEx(edgeImage, edgeImage, cv::MORPH_CLOSE, morphKernel);
}
Questions
Varying brightness, lamps, and backgrounds Manual vs. auto Canny thresholds Different morphological operations Different sharpening/blur filters (Gaussian, Median, Bilateral) Adjusting parameters on the fly with trackbars Despite these attempts, edges sometimes look great and other times are too noisy or broken.
Upvotes: 2
Views: 39