포트란
좋아, 천문학에 사용되는 FITS라는 모호한 이미지 형식을 사용하고 있습니다. 이것은 그러한 이미지를 읽고 쓰는 Fortran 라이브러리가 있음을 의미합니다. 또한 ImageMagick과 Gimp는 FITS 이미지를 읽고 쓸 수 있습니다.
내가 사용하는 알고리즘은 "Sierra Lite"디더링을 기반으로하지만 두 가지 개선 사항이 있습니다.
a) 전파 오류를 4/5로 줄입니다.
b) 합계를 일정하게 유지하면서 확산 매트릭스에 임의의 변화를 도입합니다.
이 두 가지를 함께 사용하면 OPs 예제에서 볼 수있는 패턴이 거의 완전히 사라집니다.
CFITSIO 라이브러리가 설치되어 있다고 가정하면
gfortran -lcfitsio 디더 .f90
파일 이름은 하드 코딩되어 있습니다 (이 문제를 해결하기 위해 귀찮게 할 수 없음).
암호:
program dither
integer :: status,unit,readwrite,blocksize,naxes(2),nfound
integer :: group,npixels,bitpix,naxis,i,j,fpixel,un
real :: nullval,diff_mat(3,2),perr
real, allocatable :: image(:,:), error(:,:)
integer, allocatable :: seed(:)
logical :: anynull,simple,extend
character(len=80) :: filename
call random_seed(size=Nrand)
allocate(seed(Nrand))
open(newunit=un,file="/dev/urandom",access="stream",&
form="unformatted",action="read",status="old")
read(un) seed
close(un)
call random_seed(put=seed)
deallocate(seed)
status=0
call ftgiou(unit,status)
filename='PUPPY.FITS'
readwrite=0
call ftopen(unit,filename,readwrite,blocksize,status)
call ftgknj(unit,'NAXIS',1,2,naxes,nfound,status)
call ftgidt(unit,bitpix,status)
npixels=naxes(1)*naxes(2)
group=1
nullval=-999
allocate(image(naxes(1),naxes(2)))
allocate(error(naxes(1)+1,naxes(2)+1))
call ftgpve(unit,group,1,npixels,nullval,image,anynull,status)
call ftclos(unit, status)
call ftfiou(unit, status)
diff_mat=0.0
diff_mat(3,1) = 2.0
diff_mat(1,2) = 1.0
diff_mat(2,2) = 1.0
diff_mat=diff_mat/5.0
error=0.0
perr=0
do j=1,naxes(2)
do i=1,naxes(1)
p=max(min(image(i,j)+error(i,j),255.0),0.0)
if (p < 127.0) then
perr=p
image(i,j)=0.0
else
perr=p-255.0
image(i,j)=255.0
endif
call random_number(r)
r=0.6*(r-0.5)
error(i+1,j)= error(i+1,j) +perr*(diff_mat(3,1)+r)
error(i-1,j+1)=error(i-1,j+1)+perr*diff_mat(1,2)
error(i ,j+1)=error(i ,j+1) +perr*(diff_mat(2,2)-r)
end do
end do
call ftgiou(unit,status)
blocksize=1
filename='PUPPY-OUT.FITS'
call ftinit(unit,filename,blocksize,status)
simple=.true.
naxis=2
extend=.true.
call ftphpr(unit,simple,bitpix,naxis,naxes,0,1,extend,status)
group=1
fpixel=1
call ftppre(unit,group,fpixel,npixels,image,status)
call ftclos(unit, status)
call ftfiou(unit, status)
deallocate(image)
deallocate(error)
end program dither
OP 게시물의 강아지 이미지 출력 예 :
OP 출력 예 :