# Adaptive Parallel Threshold

```csharp
public static double VariableThresholdingLocalPropertiesParallel(Bitmap image, double a, double b)
{
    int w = image.Width;
    int h = image.Height;

    BitmapData image_data = image.LockBits(
        new Rectangle(0, 0, w, h),
        ImageLockMode.ReadOnly,
        PixelFormat.Format24bppRgb);

    int bytes = image_data.Stride * image_data.Height;
    byte[] buffer = new byte[bytes];

    Marshal.Copy(image_data.Scan0, buffer, 0, bytes);
    image.UnlockBits(image_data);

    // Get global mean - this works only for grayscale images
    double mg = 0;
    for (int i = 0; i < bytes; i += 3)
    {
        mg += buffer[i];
    }
    mg /= (w * h);

    // 병렬 처리 준비: 임계값의 누적 합과 픽셀 수
    double cumulativeThreshold = 0;
    int count = 0;
    object lockObject = new object(); // 동기화 객체

    Parallel.For(1, w - 1, x =>
    {
        double localCumulativeThreshold = 0; // 각 스레드에서 임계값 누적 합산
        int localCount = 0; // 각 스레드에서 처리한 픽셀 수

        for (int y = 1; y < h - 1; y++)
        {
            int position = x * 3 + y * image_data.Stride;
            double mean = 0;
            double std = 0;

            // 3x3 주변 픽셀의 평균과 표준 편차 계산
            for (int i = -1; i <= 1; i++)
            {
                for (int j = -1; j <= 1; j++)
                {
                    int nposition = position + i * 3 + j * image_data.Stride;
                    byte pixelValue = buffer[nposition];
                    mean += pixelValue;
                    std += pixelValue * pixelValue;
                }
            }

            mean /= 9.0;
            std = Math.Sqrt(std / 9.0 - mean * mean);

            // 임계값 계산
            double threshold = a * std + b * mg;
            localCumulativeThreshold += threshold;
            localCount++;
        }

        // 누적된 결과를 메인 변수에 병합
        lock (lockObject)
        {
            cumulativeThreshold += localCumulativeThreshold;
            count += localCount;
        }
    });

    // 모든 픽셀의 평균 임계값을 반환
    return cumulativeThreshold / count;
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://til.hyunjin.space/adaptive-parallel-threshold.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
