opencv 색상 필터 그림 의 빨간색 영역 만 남기 기

그림 과 같이 이번 에는 그림 에서 줄자 의 빨간색 눈금 을 찾 아야 하기 때문에 그림 을 걸 러 내 고 빨간색 부분 만 남 겨 야 합 니 다.

처음에는 RGB 값 을 각각 찾 아 빨간색 구역 의 부분 을 찾 아 보존 하면 된다 는 생각 이 들 었 으 나 빨간색 구역 의 RGB 수치 범 위 를 확정 하기 어 려 울 것 같 아 그림 을 HSV 공간 으로 전환 해 야 한다.
opencv 에서 cvCvtColor 함 수 를 직접 사용 하면 됩 니 다.
IplImage* hsv = cvCreateImage( cvGetSize(image), 8, 3 );
cvCvtColor(image,hsv,CV_BGR2HSV);
opencv 의 H 범 위 는 0~180 이 고 빨간색 의 H 범 위 는 대략(0~8)∪(160,180)이 며 S 는 포화 도 이 며 보통 한 값 보다 크 고 S 가 낮 으 면 회색(참고 치 S>80)이 며 V 는 밝기 이 고 너무 낮 으 면 검은색 이 며 너무 높 으 면 흰색(참고 치 220>V>50)이다.
그래서 다음 에 해 야 할 일 은 그림 을 옮 겨 다 니 며 그림 의 픽 셀 마다 H,S,V 분량 을 가 져 온 다음 에 판단 을 하고 조건 을 만족 시 키 는 것 은 보류 하 며 만족 하지 않 는 것 은 검은색 으로 할당 하 는 것 입 니 다.
나 는 opencv 의 IplImage 로 그림 을 저장 합 니 다.
IplImage 에서 픽 셀 점 을 가 져 오 는 방법 은 다음 과 같 습 니 다.
CvScalar s_hsv = cvGet2D(hsv, j, i);//픽 셀 점(i,j)점 의 HSV 값 을 가 져 옵 니 다.i 는 width 값 이 고 j 는 height 값 입 니 다.
IplImage 가 픽 셀 점 에 값 을 부여 하 는 방식 은 다음 과 같 습 니 다.
CvScalar s;
cvSet2D(hsv, j ,i, s);//픽 셀 할당
각각 H,S,V 분량 을 얻 고 이미지 전환 시 BGR2HSV 에 주의 하기 때문에 s.val[0]은 B 또는 H 의 값 이 고 s.val[1]은 G 또는 S 의 값 이 며 s.val[2]은 R 또는 V 의 값 이다.
사 제 는 CvMat 를 즐겨 사용 하기 때문에 입력 은 모두 CvMat 로 바 뀌 었 습 니 다.사용 할 때 inputImage 는 필터 링 을 원 하 는 그림 이 고 outputImage 는 출력 그림 입 니 다.outputImage 는 함수 에서 공간 신청 과 할당 을 하기 때문에 인 자 를 입력 할 때 바로 NULL 로 설정 하면 됩 니 다.
또한 주의해 야 할 것 은 컬러 이미지 에 대한 실험 이기 때문에 들 어 오 는 그림 이 3 채널 의 컬러 그림 이 아니라면 메모리 오류 가 발생 할 수 있 습 니 다.
아래 그림 을 열거 나 그림 을 만 드 는 방식 은 모두 단일 채널 방식 으로 메모리 오류 가 발생 할 수 있 습 니 다.

IplImage *input = cvLoadImage(path, 0),
CvMat* M = cvCreateMat(4,4,CV_32FC1); //  8UC1,   C1  nChannel = 1,      

void colorFilter(CvMat *inputImage, CvMat *&outputImage)
{
 int i, j;
 IplImage* image = cvCreateImage(cvGetSize(inputImage), 8, 3);
 cvGetImage(inputImage, image); 
 IplImage* hsv = cvCreateImage( cvGetSize(image), 8, 3 ); 
 
 cvCvtColor(image,hsv,CV_BGR2HSV);
 int width = hsv->width;
 int height = hsv->height;
 for (i = 0; i < height; i++)
 for (j = 0; j < width; j++)
 {
 CvScalar s_hsv = cvGet2D(hsv, i, j);//      (j, i)  HSV   
 /*
 opencv  H   0~180,   H     (0~8)∪(160,180) 
 S    ,        ,S      (   S>80),
 V   ,      ,      (   220>V>50)。
 */
 CvScalar s;
 if (!(((s_hsv.val[0]>0)&&(s_hsv.val[0]<8)) || (s_hsv.val[0]>120)&&(s_hsv.val[0]<180)))
 {
 s.val[0] =0;
 s.val[1]=0;
 s.val[2]=0;
 cvSet2D(hsv, i ,j, s);
 }
 
 }
 outputImage = cvCreateMat( hsv->height, hsv->width, CV_8UC3 );
 cvConvert(hsv, outputImage);
 cvNamedWindow("filter");
 cvShowImage("filter", hsv);
 waitKey(0);
 cvReleaseImage(&hsv);
}
함수 에 관 해 한 가지 더 설명 할 것 이 있 습 니 다.H 분량 은 제 가 얻 은 것 은(0,8),(120,180)입 니 다.S 와 V 분량 은 선별 하지 않 았 습 니 다.주석 부분 에 따라 선별 하면 결과 가 좋 지 않 습 니 다.
결 과 는 그림 과 같다.

추가 지식:opencv 구현 이미지 단일 색상 배경 제거
사고의 방향

배경 은 고정된 색 이기 때문에 배경 을 쉽게 선별 한 다음 흰색 으로 완전히 투명 하 게 설정 하면 된다.
코드

#coding=utf-8
import cv2 as cv
bg_color = [197, 102, 6]
threshold = 3000

def calc_diff(pixel):
'''
  pixel         ,                 
'''
  return (pixel[0]-bg_color[0])**2 + (pixel[1]-bg_color[1])**2 + (pixel[2]-bg_color[2])**2

def remove_bg():
  image_path = './logo.png'
  logo = cv.imread(image_path)
  logo = cv.cvtColor(logo, cv.COLOR_BGR2BGRA) #           BGRA  
  h, w = logo.shape[0:2]
  for i in range(h):
    for j in range(w):
      if calc_diff(logo[i][j]) < threshold:
      #  logo[i][j]   ,        ,     
        logo[i][j][0] = 255
        logo[i][j][1] = 255
        logo[i][j][2] = 255
        logo[i][j][3] = 0
 
  cv.imwrite("./logo_rmbg.png", logo)
        
if __name__ == '__main__':
  remove_bg()
사용 방법
다섯 번 째 줄 의 bg 수정color 는 그림 배경의 bgr 값 과 여섯 번 째 줄 의 threshold(threshold 가 클 수록 덮어 쓰 는 픽 셀 이 많 습 니 다)입 니 다.
효과:

emmm,사실은 배경 근처 의 색 이 엄격 한 배경 색 이 아니 라 는 것 을 증명 합 니 다.나중에 글 자 를 채 우 면 많이 좋아 집 니 다.

이상 의 opencv 색상 필 터 는 그림 속 의 빨간색 구역 만 남 겨 두 는 작업 은 바로 작은 편집 이 여러분 에 게 공유 하 는 모든 내용 입 니 다.참고 하 시기 바 랍 니 다.여러분 들 도 저 희 를 많이 사랑 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기