图像处理:dither

36 篇文章 4 订阅
33 篇文章 3 订阅
#include<iostream>
#include<opencv2\opencv.hpp>

using namespace std;
using namespace cv;

int main() {
	Mat img_gray0 = imread("xjj.jpg", IMREAD_GRAYSCALE);
	int img_h, img_w;
	img_h = img_gray0.size().height;
	img_w = img_gray0.size().width;

	Mat img_dither = Mat::zeros(Size(img_w + 1, img_h + 1), CV_8U);
	Mat img_undither = Mat::zeros(Size(img_w, img_h), CV_8U);
	int threshold = 128;

	//@ 给img_dither赋值,对img_undither二值化
	for (int i = 0; i < img_h; i++)
	{
		for (int j = 0; j<img_w; j++)
		{
			//cout << img_dither.at<uchar>(i, j) << endl;
			img_dither.at<uchar>(i, j) = img_gray0.at<uchar>(i, j);
			if (img_gray0.at<uchar>(i, j)>threshold)
			{
				img_undither.at<uchar>(i, j) = 255;
			}
            //@ 这里还有一种二值化方式,采用随机阈值进行二值化,这种也很有意思,得到的二值图像有更多的细节
            if (img_gray0.at<uchar>(i, j)>(rand() % 255))
			{
				img_undither.at<uchar>(i, j) = 255;
			}
		}
	}

	for (int i = 0; i < img_h; i++)
	{
		for (int j = 0; j<img_w; j++)
		{
			int new_pix;
			int old_pix = img_dither.at<uchar>(i, j);
			if (img_dither.at<uchar>(i, j)>threshold)
			{
				new_pix = 255;
			}
			else
			{
				new_pix = 0;
			}
			//先对img_dither二值化
			img_dither.at<uchar>(i, j) = new_pix;
			int quant_err = old_pix - new_pix;
			if (j > 0)
			{
				img_dither.at<uchar>(i + 1, j - 1) = img_dither.at<uchar>(i + 1, j - 1) + quant_err * 3 / 16;
			}
			img_dither.at<uchar>(i + 1, j) = img_dither.at<uchar>(i + 1, j) + quant_err * 5 / 16;
			img_dither.at<uchar>(i, j + 1) = img_dither.at<uchar>(i, j + 1) + quant_err * 7 / 16;
			img_dither.at<uchar>(i + 1, j + 1) = img_dither.at<uchar>(i + 1, j + 1) + quant_err * 1 / 16;
		}
	}
	imshow("src", img_gray0);
	imshow("img_undither", img_undither);
	imshow("img_dither", img_dither);
	waitKey();
	return 0;
}

C++里面查看Mat数据没有python方便,可以把数据保存到文件查看,还挺方便的 

    std::string savedither = "./save_data.xml";
    cv::FileStorage fs(savedither, cv::FileStorage::WRITE);
    fs << "img_gray0" << img_gray0;
    fs << "img_undither" << img_undither;
    fs << "img_dither" << img_dither;
    fs.release();

参考: 

利用Floyd-Steinberg方法(dithering),将灰度图转换为二值图_whoispo的博客-CSDN博客

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用Verilog实现Jarvis dither和误差扩散的代码: ```verilog module jarvis_dither_error_diffusion( input [7:0] pixel_in, output [7:0] pixel_out, input clk, input rst ); reg signed [8:0] quant_error; reg signed [8:0] dither_noise; reg signed [8:0] dithered_pixel; reg signed [8:0] err1, err2, err3, err4, err5, err6, err7, err8; assign pixel_out = dithered_pixel; always @(posedge clk) begin if (rst) begin quant_error <= 0; dither_noise <= 0; dithered_pixel <= 0; err1 <= 0; err2 <= 0; err3 <= 0; err4 <= 0; err5 <= 0; err6 <= 0; err7 <= 0; err8 <= 0; end else begin quant_error <= pixel_in - dithered_pixel; dither_noise <= (quant_error >> 5) + (quant_error >> 6) + (quant_error >> 7) + (quant_error >> 8); dithered_pixel <= pixel_in + dither_noise + err1; err1 <= quant_error + ((dither_noise * 7) >> 4); err2 <= ((dither_noise * 5) >> 4) + err3; err3 <= ((dither_noise * 3) >> 4) + err4; err4 <= (dither_noise >> 4) + err5; err5 <= (dither_noise >> 5) + err6; err6 <= (dither_noise >> 6) + err7; err7 <= (dither_noise >> 7) + err8; err8 <= dither_noise >> 8; end end endmodule ``` 这个模块接受一个8位像素值作为输入,并使用Jarvis dither和误差扩散算法添加噪声。在每个时钟上升沿,它计算当前采样的量化误差,并加上一个由该误差的一个分数位和五分之一、六分之一、七分之一和八分之一位组成的噪声成分,以产生一个输出像素值。此外,它还将误差扩散到相邻的像素,以帮助减少量化误差产生的噪声。这种方法可以用于改善图像质量,特别是在低比特深度的情况下。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值