OpenCV全局/局部阀值二值化

来源:互联网 发布:矩阵的几为3和秩的关系 编辑:程序博客网 时间:2024/06/06 04:01

1.概念


1.1全局二值化


根据自定义阀值对图像进行二值化处理,即灰度值大于阀值时设改像素灰度值为255,灰度值小于阈值时设该像素灰度值为0

1.2局部二值化


在局部范围内根据特定算法算出局部的阀值,这个局部的大小可以自己决定(例8*8),算法也可以自己觉得,本文所用的用法是局部平局的灰度值作为阀值。得到局部阀值再进行局部二值化处理


2.局部二值化结果


原图

局部二值化结果

3.完整代码

#include "cv.h"                         #include "highgui.h"#include "cvaux.h"#include "cxcore.h"#include "opencv2/opencv.hpp"#include "opencv2/imgproc.hpp"#include <iostream>#include <string>using namespace cv;using namespace std;Mat image3;Mat target3;//全局阈值二值化void globalTwoValue(Mat src,int value){    target3 = Mat::zeros(src.size(), src.type());    for (int i = 0; i < src.rows; i++)    {        for (int j = 0; j < src.cols; j++)        {                break;            if (value > (int)src.at<uchar>(i, j))                target3.at<uchar>(i, j) = 0;            else                target3.at<uchar>(i, j) = 255;        }    }}//8*8局部二值化,阈值=局部平均灰度值void localTwoValue(Mat src){    //1.先算出一列有几个8,剩下几个像素    int countRow = src.rows / 8;    int rowLeft = src.rows % 8;    //2.算出一列有几个8,剩下几个像素    int countCol = src.cols / 8;    int colLeft = src.cols % 8;    target3 = Mat::zeros(src.size(), src.type());    for (int k = 0; k < countRow; k++)    {        for (int l = 0; l < countCol; l++)        {            int value = 0;            for (int i = k * 8; i < (k + 1) * 8; i++)            {                for (int j = l * 8; j < (l + 1) * 8; j++)                {                    value += (int)src.at<uchar>(i, j);                }            }            value = value / 64;            for (int i = k*8; i < (k + 1) * 8; i++)            {                for (int j = l * 8; j < (l + 1) * 8; j++)                {                    if ((int)src.at<uchar>(i, j) < value )                        target3.at<uchar>(i, j) = 0;                    else                        target3.at<uchar>(i, j) = 255;                }            }        }    }    //底部不足8*8部分    if (rowLeft != 0)    {        for (int k = countRow; k < countRow + rowLeft; k++)        {            for (int l = 0; l < countCol; l++)            {                int value = 0;                for (int i = countRow * 8; i < countRow * 8 + rowLeft; i++)                {                    for (int j = l * 8; j < (l + 1) * 8; j++)                    {                        value += (int)src.at<uchar>(i, j);                    }                }                value = value / (8 * rowLeft);                for (int i = countRow * 8; i < countRow * 8 + rowLeft; i++)                {                    for (int j = l * 8; j < (l + 1) * 8; j++)                    {                        if ((int)src.at<uchar>(i, j) < value)                            target3.at<uchar>(i, j) = 0;                        else                            target3.at<uchar>(i, j) = 255;                    }                }            }        }    }    //右侧不足8*8部分    if (colLeft != 0)    {        for (int k = 0; k < countRow; k++)        {            for (int l = countCol; l < countCol + colLeft; l++)            {                int value = 0;                for (int i = k * 8; i < (k + 1) * 8; i++)                {                    for (int j = countCol * 8; j < countCol * 8 + colLeft; j++)                    {                        value += (int)src.at<uchar>(i, j);                    }                }                value = value / (8 * colLeft);                for (int i = k * 8; i < (k + 1) * 8; i++)                {                    for (int j = countCol * 8; j < countCol * 8 + colLeft; j++)                    {                        if ((int)src.at<uchar>(i, j) < value)                            target3.at<uchar>(i, j) = 0;                        else                            target3.at<uchar>(i, j) = 255;                    }                }            }        }    }    //右下角 rowleft * colleft 部分    if (rowLeft != 0 && colLeft != 0)    {        int value = 0;        for (int i = 8 * countRow; i < src.rows; i++)        {            for (int j = 8 * countCol; j < src.cols; j++)            {                value += (int)src.at<uchar>(i, j);            }        }        value = value / (rowLeft * colLeft);        for (int i = 8 * countRow; i < src.rows; i++)        {            for (int j = 8 * countCol; j < src.cols; j++)            {                if ((int)src.at<uchar>(i, j) < value)                    target3.at<uchar>(i, j) = 0;                else                    target3.at<uchar>(i, j) = 255;            }        }    }}int main(){    //加上0表示读入灰度图    image3 = imread("D:/opencv/testPic/d1.bmp", 0);    if (image3.empty())    {        printf("could not load pic!\n");        return -1;    }    namedWindow("image3");    imshow("image3", image3);    localTwoValue(image3);    namedWindow("target3");    imshow("target3", target3);    imwrite("D:/opencv/testPic/d4.bmp", target3);    waitKey(0);    return 0;}