三角形分割法

三角形:
void Triangle(Mat& src, Mat& dst) {

	int i = 0, j = 0;
	int gray;
	int temp = 0;
	bool isflipped = false;

	//求直方图
	//void calcHist( const Mat* images, int nimages,
	//                const int* channels, InputArray mask,
	//	            OutputArray hist, int dims, const int* histSize,
	//	            const float** ranges, bool uniform = true, bool accumulate = false );
	//
	/*int nimages = 1;
	int channels[1] = { 0 };
	Mat calchist;
	int dims = 1;

	int histSize[1] = { 256 };
	//每一维数值的取值范围ranges
	float hranges[2] = { 0,255 };
	//每一维数值的取值范围
	const float* ranges[1] = { hranges };
	//灰度级别

	calcHist(&src, nimages, channels, Mat(), calchist, dims, histSize, ranges);
	*/

	int calchist[256] = { 0 };
	//遍历灰度图像,统计灰度级的个数
	for (i = 0; i < src.rows; i++)
	{
		uchar* p = src.ptr<uchar>(i);
		for (j = 0; j < src.cols; j++)
		{
			int value = p[j];
			calchist[value]++;
		}
	}
	
	
	//寻找直方图中两侧边界
	int left_bound = 0;
	int right_bound = 0;
	int max = 0;
	int max_index = 0;

	//左侧为零的位置
	for (i = 0; i < 256; i++) {
		if (calchist[i] > 0) {
			left_bound = i;
			break;
		}
	}
	//直方图为零的位置
	if (left_bound > 0) {
		left_bound--;
	}

	//直方图右侧为零的位置
	for (i = 255; i > 0; i--) {
		if (calchist[i] > 0) {
			right_bound = i;
			break;
		}
	}

	//直方图为零的地方
	if (right_bound > 0) {
		right_bound++;
	}

	//寻找直方图最大值
	for (i = 0; i < 256; i++) {
		if (calchist[i] > max) {
			max = calchist[i];
			max_index = i;
		}
	}

	//判断最大值是否在最左侧,如果是则不用翻转
	//因为三角形二值化只能适用于最大值在最右侧
	if (max_index - left_bound < right_bound - max_index) {
		isflipped = true;
		i = 0;
		j = 255;
		while (i < j) {
			//左右交换
			temp = calchist[i];
			calchist[i] = calchist[j];
			calchist[j] = temp;
			i++;
			j--;
		}
		left_bound = 255 - right_bound;
		max_index = 255 - max_index;

	}

	//求阈值
	double thresh = left_bound;
	double a, b, dist = 0, tempdist;
	a = max;
	b = left_bound - max_index;
	for (int i = left_bound+1; i <= max_index; i++)
	{
		//计算距离--不需要真正计算
		tempdist = a * i + b * calchist[i];
		if (tempdist > dist) {
			dist = tempdist;
			thresh = i;
		}
	}
	thresh--;

	// 对已经得到的阈值T,如果前面已经翻转了,则阈值要用255-T
	if (isflipped)
	{
		thresh = 255 - thresh;
	}

	//二值化
	Threshold(image, dst, thresh);
	
    

}
def thresh_trangle(img):
    sum_pixel = 0
    sum_count = 0
    min_pixel = 256
    max_pixel = 0
    h,w = img.shape[0:2]
    calchist = np.zeros(256,dtype=np.int) #灰阶
    isflipped = False
    for i in range(h):
        for j in range(w):
            if mask[i][j] == 255:
                calchist[int(img[i][j])]+=1
            else:
                pass
    
    # calchist = hist_array
    left_bound,right_bound,max,max_index = 0,0,0,0
    #左侧为零的位置
    for i in range(256):
        if calchist[i] > 0:
            left_bound = i
            break
	#直方图为零的位置
    if left_bound > 0:
        left_bound-=1
    #直方图右侧为零的位置
    for i in range(255,0,-1):
        if calchist[i] > 0:
            right_bound = i
            break
    #直方图为零的地方
    if right_bound > 0:
        right_bound+=1
    #寻找直方图最大值
    for i in range(256):
        if calchist[i] > max:
            max = calchist[i]
            max_index = i
    #判断最大值是否在最左侧,如果是则不用翻转
	#因为三角形二值化只能适用于最大值在最右侧
    if max_index - left_bound < right_bound - max_index:
        isflipped = True
        i = 0
        j = 255
        while i < j:
			#左右交换
            temp = calchist[i]
            calchist[i] = calchist[j]
            calchist[j] = temp
            i+=1
            j-=1
        left_bound = 255 - right_bound
        max_index = 255 - max_index
    #求阈值
    thresh = left_bound
    dist = 0
    a = max
    b = left_bound - max_index
    for i in range(left_bound+1,max_index+1,1):
		#计算距离--不需要真正计算
        tempdist = a * i + b * calchist[i]
        if tempdist > dist:
            dist = tempdist
            thresh = i
    thresh-=1 #经验值
    #对已经得到的阈值T,如果前面已经翻转了,则阈值要用255-T
    if isflipped:
        thresh = 255 - thresh
    # 阈值化
    img[img>=thresh] = 255
    img[img<thresh] = 0
    return thresh,img

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值