zoukankan      html  css  js  c++  java
  • OpenCV学习(8)

    OpenCV仿射变换

     1 int warpExample(void) {
     2     // OpenCV仿射变换 
     3     // T = M × X
     4     cv::Point2f srcTri[3];
     5     cv::Point2f dstTri[3];
     6     cv::Mat rotMat(2, 3, CV_32FC1);
     7     cv::Mat warpMat(2, 3, CV_32FC1);
     8     cv::Mat src, warpDst, warpRotateDst;
     9     src = cv::imread("dog.jpg", cv::IMREAD_COLOR);
    10 
    11     if (src.empty())
    12         return -1;
    13 
    14     warpDst = cv::Mat::zeros(src.rows, src.cols, src.type());
    15     srcTri[0] = cv::Point2f(0, 0);
    16     srcTri[1] = cv::Point2f(src.cols - 1.f, 0);
    17     srcTri[2] = cv::Point2f(0, src.cols - 1.f);
    18     dstTri[0] = cv::Point2f(src.cols * 0.0f, src.rows * 0.33f);
    19     dstTri[1] = cv::Point2f(src.cols * 0.85f, src.rows * 0.25f);
    20     dstTri[2] = cv::Point2f(src.cols * 0.15f, src.rows * 0.7f);
    21 
    22     // 通过3点对应关系获得反射变换矩阵
    23     // https://blog.csdn.net/claroja/article/details/83624701
    24     warpMat = cv::getAffineTransform(srcTri, dstTri);
    25     // 仿射变换
    26     // https://www.xuebuyuan.com/509229.html
    27     cv::warpAffine(src, warpDst, warpMat, warpDst.size());
    28 
    29     cv::Point center = cv::Point(warpDst.cols / 2, warpDst.rows / 2);
    30     double angle = -50.0;
    31     double scale = 0.6;
    32 
    33     // 获得仿射变化矩阵 参数:中心点 旋转角度 缩放比例
    34     rotMat = cv::getRotationMatrix2D(center, angle, scale);
    35     cv::warpAffine(warpDst, warpRotateDst, rotMat, warpDst.size());
    36     cv::namedWindow("Src", cv::WINDOW_AUTOSIZE);
    37     cv::imshow("Src", src);
    38     cv::namedWindow("Warp", cv::WINDOW_AUTOSIZE);
    39     cv::imshow("Warp", warpDst);
    40     cv::namedWindow("WarpRotate", cv::WINDOW_AUTOSIZE);
    41     cv::imshow("WarpRotate", warpRotateDst);
    42     // 展示了通过两种不同的方式获取仿射矩阵 在对图像作仿射变换
    43 
    44     cv::waitKey(0);
    45     return 0;
    46 }

    图像直方图与其均衡化

    int equalizeHistExample(void) {
        // 图像直方图与其均衡化
        cv::Mat src = cv::imread("dog.jpg", cv::IMREAD_COLOR);
        if (src.empty())
            return -1;
    
        cv::Mat dst;
        cv::cvtColor(src, src, cv::COLOR_BGR2GRAY);
        // 图像直方图均衡化
        cv::equalizeHist(src, dst);
        cv::namedWindow("Src", cv::WINDOW_AUTOSIZE);
        cv::namedWindow("Dst", cv::WINDOW_AUTOSIZE);
        // 可以看到图像对比度增强的了
        cv::imshow("Src", src);
        cv::imshow("Dst", dst);
    
        cv::waitKey(0);
        return 0;
    }
    
    
    int calcHistExample(void) {
        // 图像直方图的计算 绘制出直方图
        cv::Mat src, dst;
        src = cv::imread("dog.jpg", cv::IMREAD_COLOR);
        if (src.empty())
            return -1;
    
        vector<cv::Mat> bgrPlanes;
        // 图像通道的分离
        cv::split(src, bgrPlanes);
        int histSize = 256;
        float range[] = { 0, 256 };
        const float* histRange = { range };
        bool uniform = true;
        bool accumulate = false;
        cv::Mat bHist, gHist, rHist;
        // 直方图的计算
        // https://blog.csdn.net/shuiyixin/article/details/80032167
        cv::calcHist(&bgrPlanes[0], 1, 0, cv::Mat(), bHist, 1, &histSize, &histRange, uniform, accumulate);
        cv::calcHist(&bgrPlanes[1], 1, 0, cv::Mat(), gHist, 1, &histSize, &histRange, uniform, accumulate);
        cv::calcHist(&bgrPlanes[2], 1, 0, cv::Mat(), rHist, 1, &histSize, &histRange, uniform, accumulate);
    
        // 绘制图像直方图
        int histW = 512, histH = 400;
        // cvRound返回跟参数最接近的整数值,即四舍五入 https://blog.csdn.net/sinat_36264666/article/details/78849125
        int binW = cvRound((double)histW / histSize);
        cv::Mat histImage(histH, histW, CV_8UC3, cv::Scalar(0, 0, 0));
        cv::normalize(bHist, bHist, 0, histImage.rows, cv::NORM_MINMAX, -1, cv::Mat());
        cv::normalize(gHist, gHist, 0, histImage.rows, cv::NORM_MINMAX, -1, cv::Mat());
        cv::normalize(rHist, rHist, 0, histImage.rows, cv::NORM_MINMAX, -1, cv::Mat());
    
        // 绘制直方图 一点没有Python方便
        for (int i = 1; i < histSize; i++) {
            cv::line(histImage, cv::Point(binW * (i - 1), histH - cvRound(bHist.at<float>(i - 1))), cv::Point(binW * (i), histH - cvRound(bHist.at< float>(i))), cv::Scalar(255, 0, 0), 2, 8, 0);
            cv::line(histImage, cv::Point(binW * (i - 1), histH - cvRound(gHist.at<float>(i - 1))), cv::Point(binW * (i), histH - cvRound(gHist.at< float>(i))), cv::Scalar(0, 255, 0), 2, 8, 0);
            cv::line(histImage, cv::Point(binW * (i - 1), histH - cvRound(rHist.at<float>(i - 1))), cv::Point(binW * (i), histH - cvRound(rHist.at< float>(i))), cv::Scalar(0, 0, 255), 2, 8, 0);
        }
    
        cv::namedWindow("calcHist Demo", cv::WINDOW_AUTOSIZE);
        cv::imshow("calcHist Demo", histImage);
    
    
        cv::waitKey(0);
        return 0;
    }
     1 int compareHistExample(void) {
     2     cv::Mat srcBase, hsvBase;
     3     cv::Mat srcTest1, hsvTest1;
     4     cv::Mat srcTest2, hsvTest2;
     5     cv::Mat hsvHalfDown;
     6 
     7     srcBase = cv::imread("sky1.jpg", cv::IMREAD_COLOR);
     8     srcTest1 = cv::imread("sky2.jpg", cv::IMREAD_COLOR);
     9     srcTest2 = cv::imread("sky3.jpg", cv::IMREAD_COLOR);
    10 
    11     // if ()
    12     cv::cvtColor(srcBase, hsvBase, cv::COLOR_BGR2HSV);
    13     cv::cvtColor(srcTest1, hsvTest1, cv::COLOR_BGR2HSV);
    14     cv::cvtColor(srcTest2, hsvTest2, cv::COLOR_BGR2HSV);
    15 
    16     hsvHalfDown = hsvBase(cv::Range(hsvBase.rows / 2, hsvBase.rows - 1), cv::Range(0, hsvBase.cols - 1));
    17     int hBins = 50, sBins = 60;
    18     int histSize[] = { hBins, sBins };
    19     float hRanges[] = { 0, 180 };
    20     float sRanges[] = { 0, 256 };
    21     const float* ranges[] = { hRanges, sRanges };
    22 
    23     int channels[] = { 0, 1 };
    24     cv::MatND histBase, histHalfDown, histTest1, histTest2;
    25 
    26     cv::calcHist(&hsvBase, 1, channels, cv::Mat(), histBase, 2, histSize, ranges, true, false);
    27     cv::normalize(histBase, histBase, 0, 1, cv::NORM_MINMAX, -1, cv::Mat());
    28 
    29     cv::calcHist(&hsvHalfDown, 1, channels, cv::Mat(), hsvHalfDown, 2, histSize, ranges, true, false);
    30     cv::normalize(histHalfDown, histHalfDown, 0, 1, cv::NORM_MINMAX, -1, cv::Mat());
    31 
    32     cv::calcHist(&hsvTest1, 1, channels, cv::Mat(), hsvTest1, 2, histSize, ranges, true, false);
    33     cv::normalize(histTest1, histTest1, 0, 1, cv::NORM_MINMAX, -1, cv::Mat());
    34 
    35     cv::calcHist(&hsvTest2, 1, channels, cv::Mat(), hsvTest2, 2, histSize, ranges, true, false);
    36     cv::normalize(histTest2, histTest2, 0, 1, cv::NORM_MINMAX, -1, cv::Mat());
    37 
    38     for (int i = 0; i < 4; i++) {
    39         int compareMethod = i;
    40         double baseBase = cv::compareHist(histBase, histBase, compareMethod);
    41         double baseHalf = cv::compareHist(histBase, histHalfDown, compareMethod);
    42         double baseTest1 = cv::compareHist(histBase, histTest1, compareMethod);
    43         double baseTest2 = cv::compareHist(histBase, histTest2, compareMethod);
    44 
    45         printf("Method [%d] Perfect, Base-Half, Base-Test1, Base-Test2 : %f, %f, %f, %f 
    ", i, baseBase, baseHalf, baseTest1, baseTest2);
    46     }
    47 
    48     cv::waitKey(0);
    49     return 0;
    50 }

    OpenCV反向投影

     1 cv::Mat src, hsv, hue;
     2 int bins = 25;
     3 
     4 void HistAndBackproj(int, void*) {
     5     cv::MatND hist;
     6     int histSize = MAX(bins, 2);
     7     float hueRange[] = { 0, 180 };
     8     const float* ranges = { hueRange };
     9     cv::calcHist(&hue, 1, 0, cv::Mat(), hist, 1, &histSize, &ranges, true, false);
    10     cv::normalize(hist, hist, 0, 255, cv::NORM_MINMAX, -1, cv::Mat());
    11     cv::MatND backproj;
    12     // 创建反向投影
    13     cv::calcBackProject(&hue, 1, 0, hist, backproj, &ranges, 1, true);
    14     cv::imshow("BackProj", backproj);
    15     int w = 400, h = 400;
    16     int binW = cvRound((double)2 / histSize);
    17     cv::Mat histImage = cv::Mat::zeros(w, h, CV_8UC3);
    18     for (int i = 0; i < bins; i++) {
    19         cv::rectangle(histImage, cv::Point(i * binW, h), cv::Point((i + 1) * binW, h - cvRound(hist.at<float>(i) * h / 255.0)), cv::Scalar(0, 0, 255), -1);
    20     }
    21     cv::imshow("Histogram", histImage);
    22 }
    23 
    24 int main(void) {
    25     // OpenCV反向投影
    26     src = cv::imread("hand1.png", cv::IMREAD_COLOR);
    27     if (src.empty())
    28         return -1;
    29 
    30     cv::cvtColor(src, hsv, cv::COLOR_BGR2HSV);
    31     hue.create(hsv.size(), hsv.depth());
    32     int ch[] = { 0, 0 };
    33     // 把输入的矩阵(或矩阵数组)的某些通道拆分复制给对应的输出矩阵(或矩阵数组)的某些通道中,其中的对应关系就由fromTo参数制定
    34     cv::mixChannels(&hsv, 1, &hue, 1, ch, 1);
    35     cv::createTrackbar("* Hue bins: ", "Source image", &bins, 180, HistAndBackproj);
    36     HistAndBackproj(0, 0);
    37     cv::imshow("Source image", src);
    38 
    39     cv::waitKey(0);
    40     return 0;
    41 }

    模板匹配

     1 bool  useMask;
     2 cv::Mat img, templ, mask, result;
     3 const char* imageWindow = "Source Image";
     4 const char* resultWindow = "Result Image";
     5 int matchMethod;
     6 int maxTrackbar = 5;
     7 
     8 void MatchingMethod(int, void*) {
     9     cv::Mat imgDisplay;
    10     img.copyTo(imgDisplay);
    11     int resultCols = img.cols - templ.cols + 1;
    12     int resultRows = img.rows - templ.rows + 1;
    13     result.create(result.rows, result.cols, CV_32FC1);
    14     bool methodAcceptsMask = (CV_TM_SQDIFF == matchMethod || matchMethod == CV_TM_CCOEFF_NORMED);
    15     if (useMask && methodAcceptsMask) {
    16         // 用于模板匹配
    17         cv::matchTemplate(img, templ, result, matchMethod, mask);
    18     }
    19     else {
    20         cv::matchTemplate(img, templ, result, matchMethod);
    21     }
    22 
    23     cv::normalize(result, result, 0, 1, cv::NORM_MINMAX, -1, cv::Mat());
    24     double minVal, maxVal;
    25     cv::Point minLoc, maxLoc, matchLoc;
    26     // minMaxLoc寻找矩阵(一维数组当作向量,用Mat定义) 中最小值和最大值的位置.
    27     cv::minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, cv::Mat());
    28     if (matchMethod == CV_TM_SQDIFF || matchMethod == CV_TM_SQDIFF_NORMED)
    29         matchLoc = minLoc;
    30     else
    31         matchLoc = maxLoc;
    32     cv::rectangle(imgDisplay, matchLoc, cv::Point(matchLoc.x + templ.cols, matchLoc.y + templ.rows), cv::Scalar::all(0), 2, 8, 0);
    33     cv::rectangle(result, matchLoc, cv::Point(matchLoc.x + templ.cols, matchLoc.y + templ.rows), cv::Scalar::all(0), 2, 8, 0);
    34     cv::imshow(imageWindow, imgDisplay);
    35     cv::imshow(resultWindow, result);
    36 }
    37 
    38 int main(void) {
    39     // 模板匹配
    40     // 查找与模板图像匹配的图像区域
    41     img = cv::imread("Lisa.png", cv::IMREAD_COLOR);
    42     templ = cv::imread("LisaFace.png", cv::IMREAD_COLOR);
    43 
    44     if (img.empty() || templ.empty())
    45         return -1;
    46 
    47     cv::createTrackbar("Method: 
     0; SQDIFF 
     1: SQDIFF NORMED 
     2: TM CCORR 
     3: TM CCORR NORMED 
     4: TM COEFF 
     5: TM COEFF NORMED", imageWindow, &matchMethod, maxTrackbar, MatchingMethod);
    48     MatchingMethod(0, 0);
    49 
    50     cv::waitKey(0);
    51     return 0;
    52 }

    图像中查找轮廓

     1 cv::Mat src, srcGray;
     2 int thresh = 100;
     3 int maxThresh = 255;
     4 cv::RNG rng(12345);
     5 
     6 void threshCallback(int, void*) {
     7     cv::Mat cannyOutput;
     8     vector<vector<cv::Point>> contours;  // 轮廓
     9     vector<cv::Vec4i> hierarchy;
    10     cv::Canny(srcGray, cannyOutput, thresh, thresh * 2, 3);  // 边缘检测
    11     // https://blog.csdn.net/guduruyu/article/details/69220296
    12     // 函数cv::findContour是从二值图像中来计算轮廓的,它可以使用cv::Canny()函数处理的图像,因为这样的图像含有边缘像素;
    13     // 也可以使用cv::threshold()或者cv::adaptiveThreshold()处理后的图像,其边缘隐含在正负区域的交界处。
    14     cv::findContours(cannyOutput, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE, cv::Point(0, 0));
    15     cv::Mat drawing = cv::Mat::zeros(cannyOutput.size(), CV_8UC3);
    16 
    17     for (size_t i = 0; i < contours.size(); i++) {
    18         cv::Scalar color = cv::Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));  // 随机选取颜色
    19         // 画出边缘曲线
    20         cv::drawContours(drawing, contours, (int)i, color, 2, 8, hierarchy, 0, cv::Point());
    21     }
    22 
    23     cv::namedWindow("Contours", cv::WINDOW_AUTOSIZE);
    24     cv::imshow("Contours", drawing);
    25 }
    26 
    27 
    28 int main(void) {
    29     // 图像中查找轮廓
    30     src = cv::imread("bowl.jpg", cv::IMREAD_ANYCOLOR);
    31     if (src.empty())
    32         return -1;
    33 
    34     cv::cvtColor(src, srcGray, cv::COLOR_BGR2GRAY);
    35     cv::blur(srcGray, srcGray, cv::Size(3, 3));
    36     cv::namedWindow("Source", cv::WINDOW_AUTOSIZE);
    37     cv::imshow("Source", src);
    38     cv::createTrackbar("Canny thresh:", "Source", &thresh, maxThresh, threshCallback);
    39     threshCallback(0, 0);
    40 
    41     cv::waitKey(0);
    42     return 0;
    43 }
     1 cv::Mat src, srcGray;
     2 int thresh = 100;
     3 int maxThresh = 255;
     4 cv::RNG rng(12345);
     5 
     6 void threshCallback(int, void*) {
     7     cv::Mat thresholdOutput;
     8     vector<vector<cv::Point>> contours;  // 轮廓
     9     vector<cv::Vec4i> hierarchy;
    10     // 使用threshold进行边缘检测
    11     cv::threshold(srcGray, thresholdOutput, thresh, 255, cv::THRESH_BINARY);
    12     cv::findContours(thresholdOutput, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE, cv::Point(0, 0));
    13     vector<vector<cv::Point>> contoursPoly(contours.size());
    14     vector<cv::Rect> boundRect(contours.size());
    15     vector<cv::Point2f> center(contours.size());
    16     vector<float> radius(contours.size());
    17 
    18     for (size_t i = 0; i < contours.size(); i++) {
    19         // approxPolyDP 主要功能是把一个连续光滑曲线折线化,对图像轮廓点进行多边形拟合。
    20         // https://blog.csdn.net/kakiebu/article/details/79824856
    21         cv::approxPolyDP(cv::Mat(contours[i]), contoursPoly[i], 3, true);
    22         // 计算轮廓的垂直边界最小矩形,矩形是与图像上下边界平行的 参数是轮廓的点集
    23         boundRect[i] = cv::boundingRect(cv::Mat(contoursPoly[i]));
    24         // 计算最小包围圆
    25         cv::minEnclosingCircle(contoursPoly[i], center[i], radius[i]);
    26     }
    27 
    28     cv::Mat drawing;
    29     for (size_t i = 0; i < contours.size(); i++) {
    30         cv::Scalar color = cv::Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
    31         cv::drawContours(drawing, contoursPoly, (int)i, color, 1, 8, vector<cv::Vec4i>(), 0, cv::Point());
    32         cv::rectangle(drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0);
    33         cv::circle(drawing, center[i], (int)radius[i], color, 2, 8, 0);
    34     }
    35 
    36     cv::namedWindow("Contours", cv::WINDOW_AUTOSIZE);
    37     cv::imshow("Contours", drawing);
    38 }
    39 
    40 int main(void) {
    41     // 为轮廓创建边界框和圆
    42     src = cv::imread("balloon.jpg", cv::IMREAD_ANYCOLOR);
    43     if (src.empty())
    44         return -1;
    45 
    46     cv::cvtColor(src, srcGray, cv::COLOR_BGR2GRAY);
    47     cv::blur(srcGray, srcGray, cv::Size(3, 3));
    48     cv::namedWindow("Source", cv::WINDOW_AUTOSIZE);
    49     cv::imshow("Source", src);
    50     cv::createTrackbar("Canny thresh:", "Source", &thresh, maxThresh, threshCallback);
    51     threshCallback(0, 0);
    52 
    53     cv::waitKey(0);
    54     return 0;
    55 }
  • 相关阅读:
    倒计时显示
    Global.asax实现屏蔽ip和图片防盗链
    同一账号不能同时登陆
    javascript中defer的作用
    javascript焦点图
    asp.net自定义分页
    GridVew linkbutton点击时获取点击行label的绑定值
    内存对齐
    深入.NET托管堆(Managed Heap)
    内存对齐1
  • 原文地址:https://www.cnblogs.com/lnlin/p/13815530.html
Copyright © 2011-2022 走看看