计算机视觉class2_Remaining

来源:互联网 发布:如何盗用淘宝图片 编辑:程序博客网 时间:2024/06/07 01:55

要点

1.阈值分割(固定阈值、变阈值、调节参数窗)
2.直方图拉伸
3.区域生长法分割

解释

1.阈值分割
阈值分割的思想就是用一个或几个阈值将图像的灰度直方图分成几个类,认为图像中的灰度值在同一个灰度类里的像素属于同一个物体。阈值分割法主要有两个步骤:①确定进行正确分割的阈值 ②将图像的所有像素的灰度级与阈值进行比较,实现区域划分,达到目标与背景分离的目的。如何正确选择阈值是算法的关键,通常也有一些方法,常用的有迭代法,自适应分割法等等。具体情况就不详述了。重点在于代码的实现上。

2.直方图拉伸
直方图拉伸的目的是为了实现直方图的均衡化,以实现一个图像增强的目的,当然均衡化并非总是我们的目标,怎样实现增强还得看具体情况,除了直方图的均衡化,还有直方图的规定化,相对来说,均衡化还是比较常见。

3.区域生长法
区域生长法是根据预先定义的生长准则,将像素或子区域组合为更大区域的过程。基本方法是从一组“种子点”开始,将与种子预先定义的性质相似的那些邻域像素添加到每个种子点上,来形成生长区域。算法设计主要关注以下三点:①生长种子点的确定 ②区域生长的条件 ③区域生长的停止条件 。对于生长点可由算法自动确定也可以认为确定,在种子点处进行8邻域扩展,判定生长准则是:若考虑的像素与种子像素灰度值的差值的绝对值小于某个门限T,则把该像素包括进种子像素所在区域。当不再有像素满足准则时,生长结束。

程序

1.阈值分割

#include <opencv2\opencv.hpp>#include <iostream>#include <vector>using namespace std;using namespace cv;#define WINDOW_NAME "code"Mat g_grayImage, g_dstImage;int g_thresholdValue = 100, g_thresholdType = 1;vector<vector<Point>> contours;vector<Vec4i> hier;double area = 0.;void on_Segement(int, void *){    threshold(g_grayImage, g_dstImage, g_thresholdValue, 255, g_thresholdType);    imshow(WINDOW_NAME, g_dstImage);    //根据参数值动态调整,计算了一个面积    findContours(g_dstImage, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));    for (int i = 0; i < (int)contours.size(); i++)    {        area = contourArea(contours[i]);        cout << "number " << i << " area is " << area << endl;    }}int main(){    g_grayImage = imread("1.jpg", 0);    namedWindow("srcImage", 1);    imshow("srcImage", g_grayImage);    namedWindow(WINDOW_NAME, 1);    createTrackbar("type:", WINDOW_NAME, &g_thresholdType, 4, on_Segement);    createTrackbar("value:", WINDOW_NAME, &g_thresholdValue, 200, on_Segement);    on_Segement(0, 0);    waitKey(0);    return 0;}

结果:
这里写图片描述这里写图片描述
(对于四种type,是指4种不同分割模式,可指定某一种)

2.直方图拉伸

#include <opencv2\opencv.hpp>#include <iostream>using namespace std;using namespace cv;Mat processedImage;Mat averageHist;Mat calHist(Mat image){    int channel = 0;    MatND dstHist;    int histSize[] = { 256 };    float range[] = { 0, 255 };    const float* ranges[] = { range };    calcHist(&image, 1, &channel, Mat(), dstHist, 1, histSize, ranges, true, false);    //Mat mean, var;    Mat drawImage = Mat::zeros(Size(256, 512), CV_8UC1);    double g_dHistMaxValue;    minMaxLoc(dstHist, 0, &g_dHistMaxValue, 0, 0);    for (int i = 0; i < 256; i++)    {        int value = cvRound(dstHist.at<float>(i) * 512 * 0.9 / g_dHistMaxValue);//同一个灰度值的像素可能非常的多,所以归一化放在窗口里        line(drawImage, Point(i, drawImage.rows - 1), Point(i, drawImage.rows - 1 - value), Scalar(255, 255, 255));    }    /*meanStdDev(image.rowRange(0, 255), var, mean);    cout << "mean:" <<mean.at<double>(0,0)<< endl;    cout << "var:" << var.at<double>(0,0) << endl;*/    return drawImage;}void transform(Mat img,int max=9){    /*for (int y = 0; y < img.rows; y++)    {        uchar* data = img.ptr<uchar>(y);        uchar* target = averageHist.ptr<uchar>(y);        for (int x = 0; x < img.cols; x++)        {            target[x] =saturate_cast<uchar>( data[x] / max*19);        }    }*/    equalizeHist(img, img);}int main(){    //int maxIntensity = 0;    Mat sourceImage = imread("F:\\c_code\\week5_3\\week5_3\\1.png");    cvtColor(sourceImage, processedImage, CV_RGB2GRAY);    imshow("grayImage", processedImage);    averageHist = processedImage.clone();    /*    for (int y = 0; y < processedImage.rows; y++)    {        uchar* data = processedImage.ptr<uchar>(y);        for (int x = 0; x < sourceImage.cols; x++)        {            if (data[x]>maxIntensity)                maxIntensity = data[x];        }    }    cout << maxIntensity << endl;    */    Mat im1=calHist(processedImage);    imshow("hist1", im1);    transform(averageHist);    imshow("average",averageHist);    Mat im2=calHist(averageHist);    imshow("hist2", im2);    waitKey(0);    return 0;}

结果:
这里写图片描述这里写图片描述
这里写图片描述这里写图片描述

3.区域生长(漫水填充)

#include <opencv2\opencv.hpp>#include <iostream>using namespace cv;using namespace std;Point seed(471,521);int value = 10;Mat src;Rect ccomp;static void onMouse(int event, int x, int y, int, void*){    if (event != CV_EVENT_LBUTTONDOWN)        return;     seed = Point(x, y);     floodFill(src, seed, Scalar(255, 255, 255), &ccomp, Scalar(value, value, value), Scalar(value, value, value), 8);     cout << seed << endl;     imshow("result", src);}int main(){    src = imread("2.png");    imshow("src", src);    floodFill(src, seed, Scalar(255, 255, 255), &ccomp, Scalar(value, value, value), Scalar(value, value, value), 8);    namedWindow("result", 1);    setMouseCallback("result", onMouse, 0);    imshow("result", src);    waitKey(0);    return 0;}

可以手动指定种子点,图就不贴了。

That’s all. 参考毛星云.《opencv3编程入门》冈萨雷斯.《数字图像处理》