判断区分三通道、单通道图片是彩色、灰度图、二值图

问题背景:一张未知图片,opencv读取进来,有几种情况都要分析

  • 3通道----彩色:(123,146,78)(147,25,36)
  • 3通道----灰度:(123,123,123)(45,45,45)
  • 3通道----二值:(0,0,0)(255,255,255)
  • 1通道----灰度:(123)(45)(67)(255)
  • 1通道----二值:(0)(255)(0)(255)

找了半天,网上大多是废话,直方图方法什么的没用!(例如:(255,0,0)(0,255,0)(0,0,255)统计三通道结果一样,所以在某个特殊情况时,彩色图会误认为灰度图、二值图)

直接上代码(只要30ms就解决了),觉得好的记得点个赞:

子函数部分:

enum color_type
{
	unknown_error = 0,
	channel_3_color = 1,//3通道彩色
	channel_3_gray = 2,//3通道灰度
	channel_3_binary = 3,//3通道二值
	channel_1_gray = 4,//1通道灰度
	channel_1_binary = 5,//1通道二值
};
//1用各个通道进行矩阵对比
color_type Judge_color(cv::Mat img)
{
	color_type color_flag;
	if (!img.data)
		return color_flag = unknown_error;

	if (img.channels() == 3)//3通道
	{
		std::vector<cv::Mat> rgbChannels(3);
		split(img, rgbChannels);
		if (!countNonZero(rgbChannels[0] != rgbChannels[1]) && !countNonZero(rgbChannels[1] != rgbChannels[2]))//3通道完全相同
		{
			//非0.255个数=总数-0个数-255个数(化简后)
			int num = countNonZero(rgbChannels[0]) + countNonZero(~rgbChannels[0]) - rgbChannels[0].rows*rgbChannels[0].cols;
			if (num)//灰度
			{
				color_flag = channel_3_gray;
			}
			else//黑白
			{
				color_flag = channel_3_binary;
			}
		}
		else//三通道不完全同,彩色图
		{
			color_flag = channel_3_color;
		}
	}
	else if (img.channels() == 1)//1通道
	{
		int num = countNonZero(img) + countNonZero(~img) - img.rows*img.cols;
		if (num)//灰度
		{
			color_flag = channel_1_gray;
		}
		else//黑白
		{
			color_flag = channel_1_binary;
		}
	}
	return color_flag;
}

主函数测试代码:

int main()
{
	cv::Mat source = cv::imread("3.png");
	color_type flag = Judge_color(source);
	Mat sourcep;
	cv::resize(source, sourcep, Size(4000, 2000));
	switch (flag)
	{
	case unknown_error:
		break;
	case channel_3_color:
		break;
	case channel_3_gray://三通道灰度--》单通道灰度
		cvtColor(sourcep, sourcep, COLOR_BGR2GRAY);
		break;
	case channel_3_binary://三通道二值--》单通道二值
		cvtColor(sourcep, sourcep, COLOR_BGR2GRAY);
		threshold(sourcep, sourcep, 128, 255, THRESH_BINARY);
		break;
	case channel_1_gray:
		break;
	case channel_1_binary://单通道灰度--》转单通道二值
		threshold(sourcep, sourcep, 128, 255, THRESH_BINARY);
		break;
	default:
		break;
	}
}

 

  • 14
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大臉喵愛吃魚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值