내장된 가우스 기능을 사용하지 않고 이미지를 흐리게 하는 방법은 무엇입니까?
네이티브 가우스 블러 공식을 사용하여 이미지를 흐리게 하고 싶다.Wikipedia 기사를 읽었는데 어떻게 구현해야 할지 모르겠어요.
공식을 사용하여 무게를 결정하려면 어떻게 해야 합니까?
MATLAB에서 제공하는 것과 같은 내장 기능을 사용하고 싶지 않습니다.
순진한 가우스 흐릿한 글씨를 쓰는 것은 사실 꽤 쉽습니다.이것은 다른 컨볼루션필터와 같은 방법으로 이루어집니다.상자와 가우스 필터의 유일한 차이점은 사용하는 매트릭스입니다.
다음과 같이 정의된 이미지가 있다고 가정합니다.
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47 48 49
50 51 52 53 54 55 56 57 58 59
60 61 62 63 64 65 66 67 68 69
70 71 72 73 74 75 76 77 78 79
80 81 82 83 84 85 86 87 88 89
90 91 92 93 94 95 96 97 98 99
3x3 박스필터 매트릭스는 다음과 같이 정의됩니다.
0.111 0.111 0.111
0.111 0.111 0.111
0.111 0.111 0.111
가우스 흐림을 적용하려면 다음을 수행합니다.
픽셀 11의 경우 픽셀 0, 1, 2, 10, 11, 12, 20, 21, 22를 로드해야 합니다.
그런 다음 픽셀 0에 3x3 블러 필터의 왼쪽 상단 부분을 곱합니다.픽셀 1은 상단 중앙, 픽셀 2, 픽셀 3은 상단 우측, 픽셀 10은 중간 좌측 등입니다.
그런 다음 그것들을 모두 더하고 결과를 픽셀 11에 씁니다.보시다시피 픽셀 11은 현재 픽셀 자체와 주변 픽셀의 평균입니다.
엣지 케이스는 좀 더 복잡해집니다.텍스처 모서리 값에는 어떤 값을 사용합니까?한 가지 방법은 반대쪽으로 감는 것입니다.이것은 나중에 타일링된 이미지에 적합합니다.또 다른 방법은 픽셀을 주변으로 밀어 넣는 것입니다.
따라서 왼쪽 위에는 다음과 같이 샘플을 배치할 수 있습니다.
0 0 1
0 0 1
10 10 11
이것을 큰 필터 커널(5x5 또는 9x9 등)까지 쉽게 확장할 수 있는 방법을 알 수 있으면 좋겠습니다.
가우스 필터와 박스 필터의 차이는 행렬에 포함되는 숫자입니다.가우스 필터는 행과 열에 걸쳐 가우스 분포를 사용합니다.
예를 들어, 다음과 같이 임의로 정의되는 필터의 경우(즉, 가우스는 아니지만 아마도 멀리 떨어져 있지 않음)
0.1 0.8 0.1
첫 번째 열은 동일하지만 위의 행의 첫 번째 항목으로 곱합니다.
0.01 0.8 0.1
0.08
0.01
두 번째 열은 동일하지만 위의 행에 있는 값에 0.8을 곱하는 식입니다.
0.01 0.08 0.01
0.08 0.64 0.08
0.01 0.08 0.01
위의 모든 것을 더하면 1이 됩니다.상기의 필터와 원래의 박스 필터의 차이는, 써진 끝의 픽셀이 중앙의 픽셀(즉, 이미 그 위치에 있는 픽셀)에 대해서 훨씬 무거운 가중치를 갖게 된다는 것입니다.이 흐릿한 현상은 주변 픽셀이 해당 픽셀에 흐릿하게 나타나기 때문에 발생합니다.이런 종류의 필터를 사용하면 흐릿하지만 고주파수 정보(픽셀 간 빠른 색상 변경)를 많이 파괴하지는 않습니다.
이런 종류의 필터는 많은 흥미로운 일들을 할 수 있습니다.현재 픽셀에서 주변 픽셀을 빼서 이러한 종류의 필터를 사용하여 에지 검출을 수행할 수 있습니다.이렇게 하면 색상의 큰 변화(고주파)만 남게 됩니다.
편집: 5x5 필터 커널은 위와 같이 정의됩니다.
예를 들어 행이 0.1 0.2 0.4 0.2 0.1인 경우 의 각 값에 첫 번째 항목을 곱하여 열을 형성한 후 두 번째 항목을 곱하여 두 번째 열을 형성하면 다음과 같은 필터가 생성됩니다.
0.01 0.02 0.04 0.02 0.01
0.02 0.04 0.08 0.04 0.02
0.04 0.08 0.16 0.08 0.04
0.02 0.04 0.08 0.04 0.02
0.01 0.02 0.04 0.02 0.01
임의의 위치를 지정하면 위치 0, 0이 단순 0.1 * 0.1임을 알 수 있습니다.위치 0, 2는 0.1 * 0.4, 위치 2, 2는 0.4 * 0.4, 위치 1, 2는 0.2 * 0.4입니다.
그것으로 충분한 설명이 되었으면 합니다.
다음은 C#에서 커널 계산에 사용한 코드의 의사 코드입니다.그러나 나는 내가 최종 조건을 올바르게 취급한다고 감히 말할 수 없다.
double[] kernel = new double[radius * 2 + 1];
double twoRadiusSquaredRecip = 1.0 / (2.0 * radius * radius);
double sqrtTwoPiTimesRadiusRecip = 1.0 / (sqrt(2.0 * Math.PI) * radius);
double radiusModifier = 1.0;
int r = -radius;
for (int i = 0; i < kernel.Length; i++)
{
double x = r * radiusModifier;
x *= x;
kernel[i] = sqrtTwoPiTimesRadiusRecip * Exp(-x * twoRadiusSquaredRecip);
r++;
}
double div = Sum(kernel);
for (int i = 0; i < kernel.Length; i++)
{
kernel[i] /= div;
}
이게 도움이 됐으면 좋겠다.
Wikipedia 문서에서 설명한 필터 커널을 사용하려면 (분리) 규약을 구현해야 합니다.작은 값의 매트릭스(커널)를 가지고, 이 커널을 이미지내의 픽셀간에 이동시켜(즉, 매트릭스의 중심이 픽셀상에 있도록), 매트릭스 요소에 겹치는 이미지 요소를 곱해, 결과의 모든 값을 합계해, 낡은 픽셀치를 이 합계치로 치환하는 것입니다.
가우스 블러는 2D 컨볼루션 대신 두 개의 1D 컨볼루션(수직 및 수평)으로 분리할 수 있어 작업 속도가 다소 빨라집니다.
특정 테크놀로지에 한정하고 싶은지는 잘 모르겠습니다만, 그렇지 않은 경우는 SVG(ScalableVectorGraphics)에 Gaushian Blur가 실장되어 있습니다.픽셀을 포함한 모든 원형이 해당된다고 생각합니다.SVG는 개방형 표준이며 광범위하게 구현된다는 장점이 있습니다.
가우스 커널은 분리 가능한 커널입니다.
따라서 -와 같은 분리형 2D Conversion을 지원하는 기능만 있으면 됩니다.
일단 입수하면, 1D 가우스 커널을 생성해, 와 같이 함수로 송신하기 위한 래퍼만 있으면 됩니다.
이 코드는 SIMD(SSE) 및 멀티스레딩(OpenMP)에 의해 가속화된 2D 이미지 컨볼루션의 직접 C 구현입니다.
프로젝트 전체는 - Image Configuration - GitHub에 의해 제공됩니다.
언급URL : https://stackoverflow.com/questions/1696113/how-do-i-gaussian-blur-an-image-without-using-any-in-built-gaussian-functions
'programing' 카테고리의 다른 글
war/WEB-INF 폴더의 리소스에 대한 파일 경로 (0) | 2022.11.01 |
---|---|
세트를 어레이로 변환하는 방법 (0) | 2022.11.01 |
상태 표시줄 및 백분율 인쇄 방법 (0) | 2022.10.30 |
Python에서 datetime.date를 UTC 타임스탬프로 변환하는 중 (0) | 2022.10.30 |
명령줄에서 PHP 스크립트 실행 (0) | 2022.10.30 |