Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ OpenCV——如何从低质量的灰度图像中获得更好的手轮廓?_C++_Opencv_Image Processing_Opencv Contour_Binary Image - Fatal编程技术网

C++ OpenCV——如何从低质量的灰度图像中获得更好的手轮廓?

C++ OpenCV——如何从低质量的灰度图像中获得更好的手轮廓?,c++,opencv,image-processing,opencv-contour,binary-image,C++,Opencv,Image Processing,Opencv Contour,Binary Image,我需要从手部图像中获取轮廓,通常我通过4个步骤处理图像: 从3个通道到1个通道获取原始RGB灰度图像: cvtColor(sourceGrayImage, sourceGrayImage, COLOR_BGR2GRAY); 使用高斯模糊过滤灰色图像: GaussianBlur(sourceGrayImage, sourceGrayImage, Size(3,3), 0); 二值灰度图像,我按高度分割图像,通常我按高度将图像分割成6幅图像,然后每幅图像我都做阈值处理: // we spli

我需要从手部图像中获取轮廓,通常我通过4个步骤处理图像:

  • 从3个通道到1个通道获取原始RGB灰度图像:

    cvtColor(sourceGrayImage, sourceGrayImage, COLOR_BGR2GRAY);
    
  • 使用高斯模糊过滤灰色图像:

    GaussianBlur(sourceGrayImage, sourceGrayImage, Size(3,3), 0);
    
  • 二值灰度图像,我按高度分割图像,通常我按高度将图像分割成6幅图像,然后每幅图像我都做阈值处理:

    // we split source picture to binaryImageSectionCount(here it's 8) pieces by its height, 
    // then we for every piece, we do threshold, 
    // and at last we combine them agin to binaryImage        
    const binaryImageSectionCount = 8;
    void GetBinaryImage(Mat &grayImage, Mat &binaryImage)
    {
        // get every partial gray image's height
        int partImageHeight = grayImage.rows / binaryImageSectionCount;
        for (int i = 0; i < binaryImageSectionCount; i++)
        {
            Mat partialGrayImage;            
            Mat partialBinaryImage;
            Rect partialRect;
            if (i != binaryImageSectionCount - 1)
            {
                // if it's not last piece, Rect's height should be partImageHeight
                partialRect = Rect(0, i * partImageHeight, grayImage.cols, partImageHeight);
            }
            else
            {
                // if it's last piece, Rect's height should be (grayImage.rows - i  * partImageHeight)
                partialRect = Rect(0, i * partImageHeight, grayImage.cols, grayImage.rows - i  * partImageHeight);
            }
    
            Mat partialResource = grayImage(partialRect);    
            partialResource.copyTo(partialGrayImage);    
            threshold( partialGrayImage, partialBinaryImage, 0, 255, THRESH_OTSU);
    
            // combin partial binary image to one piece
            partialBinaryImage.copyTo(binaryImage(partialRect));
    
            ///*stringstream resultStrm;
            //resultStrm << "partial_" << (i + 1);
            //string string = resultStrm.str();
    
            //imshow(string, partialBinaryImage);
            //waitKey(0);*/
        }
        imshow("result binary image.", binaryImage);
        waitKey(0);
        return;
    }
    
    //我们将源图片按其高度拆分为binaryImageSectionCount(这里是8块),
    //然后我们为每一件作品,我们做,
    //最后,我们将它们重新组合成二进制图像
    const binaryImageSectionCount=8;
    作废GetBinaryImage(Mat和灰度图像、Mat和binaryImage)
    {
    //获取每个局部灰度图像的高度
    int partImageHeight=grayImage.rows/binaryImageSectionCount;
    对于(int i=0;i//resultStrm我有python中的代码片段,您可以使用C中的相同方法:

    img = cv2.imread(x, 1)
    cv2.imshow("img",img)
    
    imgray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    cv2.imshow("gray",imgray)
    
    #Code for histogram equalization
    equ = cv2.equalizeHist(imgray)
    cv2.imshow('equ', equ)
    
    #Code for contrast limited adaptive histogram equalization
    #clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8,8))
    #cl2 = clahe.apply(imgray)
    #cv2.imshow('clahe2', cl2)
    
    这是我得到的结果:


    如果你的图像非常糟糕,你可以尝试我评论的代码,包括对比度有限的自适应直方图均衡化。

    在找到轮廓之前,为什么不尝试一些预处理方法来增强图像并使手部更清晰?但是我应该尝试对这两幅图像进行什么样的预处理?你能给我一些建议吗你可以试试对比度限制自适应直方图均衡化。你可以检查我发布的答案检查这些链接以获取关于主题的更多信息:和
    #include <opencv2/imgproc/imgproc.hpp>
    #include<opencv2/opencv.hpp>
    #include <opencv2/highgui/highgui.hpp>
    
    using namespace std;
    using namespace cv;
    
    
    // we split source picture to binaryImageSectionCount(here it's 8) pieces by its height, 
    // then we for every piece, we do threshold, 
    // and at last we combine them agin to binaryImage        
    const binaryImageSectionCount = 8;
    void GetBinaryImage(Mat &grayImage, Mat &binaryImage)
    {
        // get every partial gray image's height
        int partImageHeight = grayImage.rows / binaryImageSectionCount;
        for (int i = 0; i < binaryImageSectionCount; i++)
        {
            Mat partialGrayImage;            
            Mat partialBinaryImage;
            Rect partialRect;
            if (i != binaryImageSectionCount - 1)
            {
                // if it's not last piece, Rect's height should be partImageHeight
                partialRect = Rect(0, i * partImageHeight, grayImage.cols, partImageHeight);
            }
            else
            {
                // if it's last piece, Rect's height should be (grayImage.rows - i  * partImageHeight)
                partialRect = Rect(0, i * partImageHeight, grayImage.cols, grayImage.rows - i  * partImageHeight);
            }
    
            Mat partialResource = grayImage(partialRect);    
            partialResource.copyTo(partialGrayImage);    
            threshold( partialGrayImage, partialBinaryImage, 0, 255, THRESH_OTSU);
    
            // combin partial binary image to one piece
            partialBinaryImage.copyTo(binaryImage(partialRect));
    
            ///*stringstream resultStrm;
            //resultStrm << "partial_" << (i + 1);
            //string string = resultStrm.str();
    
            //imshow(string, partialBinaryImage);
            //waitKey(0);*/
        }
        imshow("result binary image.", binaryImage);
        waitKey(0);
        return;
    }
    
    
    int main(int argc, _TCHAR* argv[])
    {   
        // get image path
        string imgPath("C:\\Users\\Alfred\\Desktop\\gray.bmp");     
    
        // read image
        Mat src = imread(imgPath);
        imshow("Source", src);        
        //medianBlur(src, src, 7);  
        cvtColor(src, src, COLOR_BGR2GRAY);     
        imshow("gray", src);    
    
        // do filter
        GaussianBlur(src, src, Size(3,3), 0);   
    
        // binary image
        Mat threshold_output(src.rows, src.cols, CV_8UC1, Scalar(0, 0, 0)); 
        GetBinaryImage(src, threshold_output);
        imshow("binaryImage", threshold_output);
    
        // get biggest contour
        vector<vector<Point> > contours;    
        findContours(threshold_output,contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
        int biggestContourIndex = 0;
        int maxContourArea = -1000;
        for (int i = 0; i < contours.size(); i++)
        {       
            if (contourArea(contours[i]) > maxContourArea)
            {
                maxContourArea = contourArea(contours[i]);
                biggestContourIndex = i;
            }
        }
    
        // show biggest contour
        Mat biggestContour(threshold_output.rows, threshold_output.cols, CV_8UC1, Scalar(0, 0, 0));
        drawContours(biggestContour, contours, biggestContourIndex, cv::Scalar(255,255,255), 2, 8, vector<Vec4i>(), 0, Point());
        imshow("maxContour", biggestContour);
        waitKey(0);
    
    }
    
    img = cv2.imread(x, 1)
    cv2.imshow("img",img)
    
    imgray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    cv2.imshow("gray",imgray)
    
    #Code for histogram equalization
    equ = cv2.equalizeHist(imgray)
    cv2.imshow('equ', equ)
    
    #Code for contrast limited adaptive histogram equalization
    #clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8,8))
    #cl2 = clahe.apply(imgray)
    #cv2.imshow('clahe2', cl2)