19,468
社区成员
发帖
与我相关
我的任务
分享
// ERROR-diffusion.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "omp.h"
#include "windows.h"
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#pragma comment(lib,"opencv_core2410d.lib")
#pragma comment(lib,"opencv_highgui2410d.lib")
#pragma comment(lib,"opencv_imgproc2410d.lib")
using namespace std;
using namespace cv;
void error_diffusion(unsigned int width,
unsigned int height,
unsigned short **InputImage,
unsigned short **OutputImage
)
{
for (unsigned int i = 0;i < height-1; i++)
{
for(unsigned int j = 0;j < width; j++)
{
//计算输出像素的值
if (InputImage[i][j]<128)
{
OutputImage[i][j] = 0;
}
else{ OutputImage[i][j] = 1;}
//计算误差值
int err = InputImage[i][j] - 255*OutputImage[i][j];
//扩散误差
InputImage[i][j+1] += err * 7/16;
InputImage[i+1][j-1] += err * 7/16;
InputImage[i+1][j] += err * 7/16;
InputImage[i+1][j+1] += err * 7/16;
}
}
}
int row = 288;
//int col = width;
void error_diffusion_omp(unsigned int width,
unsigned int height,
unsigned short **InputImage,
unsigned short **OutputImage
)
{
int cpu_num = omp_get_num_procs();//cpu数
int col = width;
#pragma omp parallel private(row , col)//并行域
{
int thread_id = omp_get_num_threads();//每个线程的线程号
Sleep(20*thread_id);//根据线程短延迟
#pragma omp for
for (int i = 0; i<(height/cpu_num);i++)
{
row = row*cpu_num + thread_id;
for ( col = 0;col<width;col++)
{
//计算输出像素的值
if (InputImage[i][col]<128)
{
OutputImage[i][col] = 0;
}
else{ OutputImage[i][col] = 1;}
//计算误差值
int err = InputImage[i][col] - 255*OutputImage[i][col];
//扩散误差
InputImage[i][col+1] += err * 7/16;
InputImage[i+1][col-1] += err * 7/16;
InputImage[i+1][col] += err * 7/16;
InputImage[i+1][col+1] += err * 7/16;
}
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
string str_name = "result.pgm";
Mat image_src = imread(str_name,1);
imshow("original image",image_src);
unsigned short **InputImage = new unsigned short *[image_src.rows];
for (int i = 0;i<image_src.rows;i++)
{
InputImage[i] = new unsigned short [image_src.cols];
}
unsigned short **OutputImage = new unsigned short *[image_src.rows];
for (int i = 0;i<image_src.rows;i++)
{
OutputImage[i] = new unsigned short [image_src.cols];
}
cout<<image_src.rows;
cout<<image_src.cols;
Mat image_dst(image_src.rows,image_src.cols,CV_8U);
for(int y = 0;y < image_src.rows;y++)
{
uchar *ptr= image_src.ptr<uchar>(y);
for(int x = 0;x < image_src.cols;x++)
{
InputImage[y][x] = ptr[x];
OutputImage[y][x] = 0;
}
}
error_diffusion(image_src.cols,image_src.rows,InputImage,OutputImage);
//error_diffusion_omp(image_src.cols,image_src.rows,InputImage,OutputImage);
for(int y = 0;y < image_src.rows;y++)
{
uchar *ptr= image_dst.ptr<uchar>(y);
for(int x = 0;x < image_src.cols;x++)
{
if (OutputImage[y][x]==1)
{
ptr[x] = 255;
}
}
}
imshow("error diffusion",image_dst);
waitKey(0);
return 0;
}
InputImage[i][width] += err * 7/16;
InputImage[i+1][width] += err * 7/16;
InputImage[i+1][-1] += err * 7/16;
以及你没有对最后一行像素进行扩散误差,最后一行只需:InputImage[i][j+1] += err * 7/16;
#pragma comment(lib, "gdiplus.lib")
#include <stdlib.h>
#include <malloc.h>
#include <windows.h>
#include <gdiplus.h>
#include <assert.h>
using namespace Gdiplus;
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) {
UINT num = 0; // number of image encoders
UINT size = 0; // size of the image encoder array in bytes
ImageCodecInfo* pImageCodecInfo = NULL;
GetImageEncodersSize(&num, &size);
if(size == 0) return -1; // Failure
pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo == NULL) return -1; // Failure
GetImageEncoders(num, size, pImageCodecInfo);
for (UINT j = 0; j < num; ++j) {
if ( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 ) {
*pClsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j; // Success
}
}
free(pImageCodecInfo);
return -1; // Failure
}
void error_diffusion(unsigned int width,
unsigned int height,
unsigned short **InputImage,
unsigned short **OutputImage
)
{
for (unsigned int i = 0;i < height-1; i++)
{
for(unsigned int j = 1;j < width-1; j++)
{
//计算输出像素的值
if (InputImage[i][j]<128)
{
OutputImage[i][j] = 0;
}
else{ OutputImage[i][j] = 1;}
//计算误差值
int err = (int)InputImage[i][j] - 255*OutputImage[i][j];
//扩散误差
int v;
v=(int)InputImage[i ][j+1];v+=err*7/16;if (v>255) v=255; if (v<0) v=0;InputImage[i ][j+1]=(unsigned short)v;
v=(int)InputImage[i+1][j-1];v+=err*3/16;if (v>255) v=255; if (v<0) v=0;InputImage[i+1][j-1]=(unsigned short)v;
v=(int)InputImage[i+1][j ];v+=err*5/16;if (v>255) v=255; if (v<0) v=0;InputImage[i+1][j ]=(unsigned short)v;
v=(int)InputImage[i+1][j+1];v+=err*1/16;if (v>255) v=255; if (v<0) v=0;InputImage[i+1][j+1]=(unsigned short)v;
}
}
}
int main()
{
unsigned int j,y,x;
GdiplusStartupInput gdiplusstartupinput;
ULONG_PTR gdiplustoken;
GdiplusStartup(&gdiplustoken, &gdiplusstartupinput, NULL);
Bitmap* bmp = new Bitmap(L"gray.bmp");
UINT height = bmp->GetHeight();
UINT width = bmp->GetWidth();
unsigned short **iImg=(unsigned short **)malloc(height*sizeof(unsigned short *));
assert(iImg);
for (j=0;j<height;j++) {
iImg[j]=(unsigned short *)malloc(width*sizeof(unsigned short));
assert(iImg[j]);
}
unsigned short **oImg=(unsigned short **)malloc(height*sizeof(unsigned short *));
assert(oImg);
for (j=0;j<height;j++) {
oImg[j]=(unsigned short *)malloc(width*sizeof(unsigned short));
assert(oImg[j]);
}
Color color;
for (y=0;y<height;y++) {
for (x=0;x<width;x++) {
bmp->GetPixel(x, y, &color);
iImg[y][x]=(unsigned short)color.GetRed();
}
}
error_diffusion(width,height,iImg,oImg);
Bitmap *clone = bmp->Clone(0,0,width,height,PixelFormat24bppRGB);
for (y=0;y<height;y++) {
for (x=0;x<width;x++) {
if (oImg[y][x]==1) color.SetValue(0xFFFFFFFF);
else color.SetValue(0xFF000000);
clone->SetPixel(x, y, color);
}
}
CLSID encoderClsid;
GetEncoderClsid(L"image/bmp",&encoderClsid);
clone->Save(L"diffusion.bmp",&encoderClsid);
delete clone;
for (j=0;j<height;j++) free(oImg[j]);
free(oImg);
for (j=0;j<height;j++) free(iImg[j]);
free(iImg);
delete bmp;
GdiplusShutdown(gdiplustoken);
return 0;
}