2013-04-18 4 views
3

제 과제물에 도움이 필요합니다.픽셀에서 RGB 색상을 비교하고 가장 가까운 색상으로 원래 색상을 변경하십시오.

  • 부하에게 PictureBox
  • 에 이미지 (255) 간의 차이 (최대 값)과, 각 화소의 R 값, 255 G의 차이를 계산한다 : 기본적으로, 이는 내가 원하는 무엇 값 및 B 값의 경우
  • 위의 계산에서 절대 값이 가장 작 으면 픽셀의 색상이 해당 색상에 더 가깝다는 것을 나타냅니다 (예 : (255-R 값)이 절대 값이 가장 작기 때문에 픽셀이 더 가깝습니다). 해당 색상)
  • 더 가까운 색상으로 픽셀 색상을 변경하십시오 (위의 예에서 빨간색으로 변경한다는 의미입니다)
  • I는 그 삼원색으로 화상을 얻는 것, 출력 한 결과에 PictureBox

의 결과를 보여준다.

나는 다음과 같은 코드를 작성했습니다 :

Bitmap img = new Bitmap(InputPictureBox.Image); 
     byte R, G, B; 
     Color pixelColor; 
     for (int x = 0; x < img.Width; x++) 
     { 
      for (int y = 0; y < img.Height; y++) 
      { 
       pixelColor = img.GetPixel(x, y); 
       R = (byte) Math.Abs(pixelColor.R - 255); 
       G = (byte) Math.Abs(pixelColor.G - 255); 
       B = (byte) Math.Abs(pixelColor.B - 255); 

       if (R < G && R < B) 
       { 
        pixelColor = Color.Red; 
       } 
       else if (G < R && G < B) 
       { 
        pixelColor = Color.Green; 
       } 
       else if (B < R && B < G) 
       { 
        pixelColor = Color.Blue; 
       } 
      } 
     } 
    OutputPictureBox.Image = img; 

문제는 컬러 이미지를 한 후 반전 할 차례이다. 그래서, 내 코드에서 무엇이 잘못 되었습니까? 나는 if 문장이 작동하지 않는다고 생각하지만 그 이유는 모른다. 내가 잘못?

내 코드와 관련된 질문이 하나 더 있는데 실제로 R/G/B 값의 차이를 계산하여 실제로 작동 할 수 있습니까? 아니면 euclidean 거리를 사용하여 절대 완료해야합니까?

이 문제를 해결하는 방법이나 코드를 작성하는 방법을 알려주십시오. 나는 아주 비슷한 질문을 읽었지 만 주어진 답은 여전히 ​​나에게 단서를주지 못했다.

+0

관리되는 API를 사용하여 비트 맵 데이터에 액세스하는 것은 일반적으로 너무 느립니다. 안전하지 않은 함수 포인터를 사용하여 비트 맵 데이터를 직접 읽고 조작하는 것을 고려하십시오. 여기에 내가 좋아하는 좋은 기사가있다. http://www.bobpowell.net/lockingbits.htm –

+1

'Math.Abs ​​(pixelColor.R - 255)'를 '255 - pixelColor.R'로 바꾸는 것이 좋다. 어쨌든 항상 긍정적 일 것입니다. –

+0

@ByteBlast 아, 네, 당신의 의견을 남겨주세요. 안전하지 않은 모드, lockbits에 대한 몇 가지 자료를 읽었지만 지금은 위의 코드를 수정하는 방법을 알고 싶습니다. –

답변

4

귀하의 코드는 실제로 작동, 그것으로 넣어 지나친의 비트가 있지만.

이 시도 :

를 코드는 게시물의 하단에있는 업데이트 섹션으로 이동되었습니다

결과 :

Result


나는 overthinking 부분 인을 삭제했습니다.

  • 왜 색상 구성 값을 반전해야하는지 이유는 없습니다 (적어도 질문을 읽으면서).

    1. 간단히 R = pixelColor.R을 수행하면됩니다. 당신이 이를 통해

    2. 그리고

    3. 이로 생각하지 "붉은 의 적어도 양을 가지고있는"것이 아니라 "는 빨간색의 가장 양을 가지고 경우, 그것의 빨간! "

  • LightStriker pointed out로 : 당신은 이미지로 다시 새로운 값을 설정 (이 코드에서 아무데도) 코드를 누락;

    1. 이것은 img.SetPixel(x, y, pixelColor)을 사용하여 수행됩니다.
  • 나는 가 단일 색상 구성 요소 모두 다른 사람보다 큰없는 경우 픽셀과 일치하는 else 절을 추가했습니다.

    1. 예를 들어 노란색 (255, 255, 0)은 규칙과 일치하지 않습니다.

    2. 이 답변의 버전을 사용하면 Black 픽셀로 바뀝니다.


업데이트 : 추가 설명을 요청 comments below. 여기에 더 많은 조건문을 추가하는 방법은 다음과 같습니다

이 업데이트 된 코드와
// NEW (start) -------------------------------------------------- 
Color[] randomizedColors = new Color[] { Color.Red, Color.Green, Color.Blue }; 
Random randomizer = new Random(); 
// NEW (end) -------------------------------------------------- 

Bitmap img = new Bitmap(InputPictureBox.Image); 
byte R, G, B; 
Color pixelColor; 

// NEW (start) -------------------------------------------------- 
Func<int, Color> ColorRandomizer = (numberOfColors) => 
{ 
    if (numberOfColors > randomizedColors.Length) 
    { 
     numberOfColors = randomizedColors.Length; 
    } 
    return randomizedColors[randomizer.Next(numberOfColors)]; 
}; 
// NEW (end) -------------------------------------------------- 

for (int x = 0; x < img.Width; x++) 
{ 
    for (int y = 0; y < img.Height; y++) 
    { 
     pixelColor = img.GetPixel(x, y); 
     R = pixelColor.R; 
     G = pixelColor.G; 
     B = pixelColor.B; 

     if (R > G && R > B) 
     { 
      pixelColor = Color.Red; 
     } 
     else if (G > R && G > B) 
     { 
      pixelColor = Color.Green; 
     } 
     else if (B > R && B > G) 
     { 
      pixelColor = Color.Blue; 
     } 
// NEW (start) -------------------------------------------------- 
     else if (pixelColor == Color.Yellow) 
     { 
      // 2 = Red or Green 
      pixelColor = ColorRandomizer(2); 
     } 
     else if (pixelColor = Color.FromArgb(152, 152, 152)) 
     { 
      // 3 = Red, Green, or Blue 
      pixelColor = ColorRandomizer(3); 
     } 
     /* else if (pixelColor = Some_Other_Color) 
     { 
      // 3 = Red, Green, or Blue 
      pixelColor = ColorRandomizer(3); 
     } */ 
// NEW (end) -------------------------------------------------- 
     else 
     { 
      pixelColor = Color.Black; 
     } 
     img.SetPixel(x, y, pixelColor); 
    } 
} 

OutputPictureBox.Image = img; 

randomizedColors 배열에 무작위로 고른해야 모든 색상을 추가 할 수 있습니다. 람다 함수 ColorRandomizer을 사용하여 색상을 임의로 선택하는 데 도움을줍니다. 이 함수는 첫 번째 요소 인 과 임의로 지정된 요소 중 하나를 임의로 선택한다는 점에 유의하십시오.

+0

오, 이제 알겠습니다. 이것은 실제로 작동합니다! 정말 고맙습니다! :) –

+0

늦게 추가 질문에 대해 죄송합니다. 검정색을 사용하지 않으려는 경우 (예 : 노란색 (255, 255, 0)) 프로그램에서 빨강과 녹색 중 하나를 선택하도록 할 수 있습니다. 난수를 생성 할 때와 비슷한 방법을 사용합니까? 두 가지 방법 (예 : pixelColor = Color.Red 및 pixelColor = Color.Green) 또는 세 가지 방법 중 하나를 선택할 수 있습니까? –

+0

@feanifarida 물론입니다! 그것은 모두 우선 순위에 달려 있습니다. 우선 순위를 원하면 ** 기존 조건 ('if' 문) 앞에 ** ** 추가하십시오. 다른 한편으로는, * after *로 간주되기를 원한다면, 간단히 하단에 추가하십시오. – Jesse

0

다음은 모든 색상을 반전합니다.

R = (byte) Math.Abs(pixelColor.R - 255); 
G = (byte) Math.Abs(pixelColor.G - 255); 
B = (byte) Math.Abs(pixelColor.B - 255); 

당신은 사용할 수 있습니다

R = (byte) pixelColor.R; 
G = (byte) pixelColor.G; 
B = (byte) pixelColor.B; 
+2

if 문을 읽으면 틀린 것을 알 수 있습니다. –

관련 문제