2017-11-20 1 views
0

Result screen imageWie lösche ich einen weißen Hintergrund in OpenCV mit C++?

Dieses Programm zeigt sequenzielle Bilder mit Bildern.

Wie Sie jedoch sehen, hat das Wurmbild einen weißen Hintergrund.

Aber ich habe bereits den Hintergrund des Wurmbildes geschnitten, also ist der aktuelle Hintergrund der Wurmbilder transparent.

Ich möchte den Hintergrund des Wurmbildes transparent verarbeiten und das Wurmbild nicht grau, sondern bunt darstellen.

Ich habe versucht, in cvtColor (Bild, srcBGR, CV_BGR2BGRA) zu bearbeiten, trat jedoch Fehler auf.

worm image

Hier ist der Code.

#include<opencv2/core.hpp> 
#include<opencv2/highgui.hpp> 
#include<opencv2/imgproc.hpp> 
#include<iostream> 
#include<vector> 

using namespace std; 
using namespace cv; 

int main(){ 
    VideoCapture cap; 
    cap.open(0); 

    if(!cap.isOpened()){ 
     cerr << "Error opening the webcam!" << endl; 
     return -1; 
    } 
    Mat image = imread("images/worm.png", 0); 
    cv::resize(image,image,Size(70, 120)); 
    Mat frame; 
    while(1){ 
     cap >> frame; 
     Mat newFrame = frame.clone(); 
     int cx = (newFrame.cols - 70)/2; 
     if (!image.empty()) { 
      // Get a BGR version of the face, since the output is BGR color 
      Mat srcBGR = Mat(image.size(), CV_8UC3); 
      cvtColor(image, srcBGR, CV_GRAY2BGR); 
      // Get the destination ROI (and make sure it is within the image) 
      Rect dstRC = Rect(cx, newFrame.rows/2, 70, 120); 
      Mat dstROI = newFrame(dstRC); 
      // Copy the pixels from src to dst. 
      srcBGR.copyTo(dstROI); 
     } 
     imshow("frame", newFrame); 
     char key = (char) waitKey(30); 
     // Exit this loop on escape: 
     if(key == 27) 
      break; 
    } 

    return 0; 
} 

Antwort

0

Try this:

#include <windows.h> 
#include <iostream> 
#include <vector> 
#include <stdio.h> 
#include "fstream" 
#include "iostream" 
#include <algorithm> 
#include <iterator> 
#include "opencv2/opencv.hpp" 

using namespace std; 
using namespace cv; 

//----------------------------------------------------------------------------------------------------- 
// 
//----------------------------------------------------------------------------------------------------- 
int main(int argc, unsigned int** argv) 
{ 
    Mat img = imread("background.jpg", 1); 
    if (img.empty()) 
    { 
     cout << "Can't read image." << endl; 
     return 0; 
    } 

    Mat overlay = imread("overlay.png", -1); 

    if (overlay.empty()) 
    { 
     cout << "Can't read overlay image." << endl; 
     return 0; 
    } 


    Rect target_roi(0,0,img.cols,img.rows); // Set here, where to place overlay. 

    cv::resize(overlay, overlay, Size(target_roi.width, target_roi.height)); 

    Mat mask; 
    if (overlay.channels() == 4) 
    { 
     vector<Mat> ch; 
     split(overlay, ch); 
     mask = 255-ch[3].clone(); 
     mask.convertTo(mask, CV_32FC1, 1.0/255.0); 
     ch.erase(ch.begin()+3); 
     merge(ch, overlay); 
    } 

    else 
    { 
     if (overlay.channels() == 3) 
     { 
      cvtColor(overlay, overlay, COLOR_BGR2GRAY); 
     } 

     overlay.convertTo(mask, CV_32FC1, 1.0/255.0); 
    } 


    for (int i = 0; i < overlay.rows; ++i) 
    { 
     for (int j = 0; j < overlay.cols; ++j) 
     { 
      float blending_coeff = mask.at<float>(i, j); 

      Vec3b v1 = img.at<Vec3b>(i + target_roi.y, j + target_roi.x); 
      Vec3b v2; 
      if (overlay.channels() == 1) 
      { 
       int v = overlay.at<uchar>(i, j); 
       v2 = (v, v, v); 
      } 
      else 
      { 
       v2 = overlay.at<Vec3b>(i, j); 
      } 

      Vec3f v1f(v1[0], v1[1], v1[2]); 
      Vec3f v2f(v2[0], v2[1], v2[2]); 

      Vec3f r = v1f*blending_coeff + (1.0 - blending_coeff)*v2f; 
      img.at<Vec3b>(i + target_roi.y, j + target_roi.x) = r; 
     } 
    } 

    imshow("mask", img); 
    imwrite("result.png", img); 
    waitKey(); 
} 
+0

Funktioniert dieser Code? Fehlermeldungen werden gedruckt ... Also, ich versuche den Fehler zu erkennen !! Vielen Dank!! –

+0

Ja, arbeitete für mich. Welchen Fehler bekommst du? –

+0

Entschuldigung, ich hatte einen Fehler ... Ihr Code funktioniert auch für mich. Wirklich danke dir!!! –

1

das Bild

Mat image = imread("images/worm.png", 0); 

verwendet, wird die Transparenzinformationen und laden Sie es als ein RGB-Bild verwerfen. Stattdessen können Sie

Mat image = imread("images/worm.png", cv2.IMREAD_UNCHANGED); 

Der Rest des Codes verwenden sollte jetzt funktionieren, da Sie das aufgenommene Bild zu einem BGRA Bild vor dem Kopieren zu konvertieren.

+0

Dank !! Dieser Code gilt jedoch für "Python". Also, ich habe versucht, in C++ - Code zu ändern, aber der Fehler wurde gedruckt ... Ich versuche, den Fehler zu korrigieren. –

1

Ich versuche es in Python zu demonstrieren.

Wie die Vorschau Antwort sagte, die cv2.imread(fname, 0) wird die Transparenzinformationen verwerfen, das ist die alpha channel.

Um die alpha channel zu erhalten, verwenden Sie cv2.imread(fname, -1) oder gleich zu cv2.imread(fname, cv2.IMREAD_UNCHANGED) zu lesen, dann teilen Sie die Kanäle.

enter image description here

können wir deutlich die alpha channel finden.

Dann tun mask-operation-blend, werden wir diese:

enter image description here


## read the images 
## 读图(0:BGR, -1:保持不变) 
wali = cv2.imread("wali.png") 
worm = cv2.imread("worm.png", -1) 

## split and merge channels 
## 通道分离与合并 
w,h = worm.shape[:2] 
b,g,r,a = cv2.split(worm) 
mask = np.dstack((a,a,a)) 
worm = np.dstack((b,g,r)) 

## mask operation 
## 掩模操作 
canvas = wali[100:100+h, 200:200+w] 
imask = mask>0 
canvas[imask] = worm[imask] 

## display 
## 显示 
cv2.imshow("wali", wali) 
cv2.waitKey() 
+0

Danke !! Ich versuche die Maskenoperation zu lernen. –

Verwandte Themen