2014年8月22日金曜日

グラフ読み取り

PyQtでグラフを読み取れるアプリを作った。
グラフの画像をCtrl+Vでペーストし、その座標をクリックすると画素値からグラフの値を教えてくれる。

最初に右クリックで左下と右上の座標を教える必要がる。
なんでこんなんがいるかって、世の中紙でデータを保存する人がまだいるということである。

(OpenCVは使っていない)

from PyQt4 import QtGui, QtCore, QtCore
import sys
import cv2
import numpy as np

def convert_array_to_qimg(cv_img):
    """
    this is based on https://stackoverflow.com/questions/18676888/how-to-configure-color-when-convert-numpy-array-to-qimage
    """
    height, width, bytesPerComponent = cv_img.shape
    bytesPerLine = bytesPerComponent * width;
    #cv2.cvtColor(cv_img, cv2.CV_BGR2RGB)
    return QtGui.QImage(cv_img.data, width, height, bytesPerLine, QtGui.QImage.Format_RGB888)

class GraphCoordinate:
    def __init__(self):
        pass

    def setBottomPixelCoordinate(self, x1, y1):
        """
        x1 and y1 are pixel
        """
        self.x1 = x1
        self.y1 = y1

    def setBottomGraphCoordinate(self, X1, Y1):
        self.X1 = X1
        self.Y1 = Y1
        print "(X1, Y1) = (%.2f, %.2f)" % (self.X1, self.Y1)


    def setTopPixelCoordinate(self, x2, y2):
        self.x2 = x2
        self.y2 = y2

    def setTopGraphCoordinate(self, X2, Y2):
        self.X2 = X2
        self.Y2 = Y2
        print "(X2, Y2) = (%.2f, %.2f)" % (self.X2, self.Y2)

    def getGraphCoordinate(self, x, y):
        w = x - self.x1 
        h = self.y1 - y
        W = self.x2 - self.x1 
        H = self.y1 - self.y2 
        X = self.X1 + w * (self.X2 - self.X1) / float(W)
        Y = self.Y1 + h * (self.Y2 - self.Y1) / float(H)
        return X, Y 



class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.image_frame = QtGui.QLabel()
        fname = r"sample08.png"
        img = cv2.imread(fname)
        #img = QtGui.QImage(fname)
        qimg = convert_array_to_qimg(img)
        self.image_frame.setPixmap(QtGui.QPixmap.fromImage(qimg))
        self.clip = QtGui.QApplication.clipboard()
        
        self.setCentralWidget(self.image_frame)
        self.move(30,30)

        self.counter = 0
        self.coord = GraphCoordinate()
 
    def keyPressEvent(self, e):

        if (e.modifiers() & QtCore.Qt.ControlModifier):
            #selected = self.table.selectedRanges()
            if e.key() == QtCore.Qt.Key_V:#past
                qimg = self.clip.image()
                self.displayImage(qimg)

            elif e.key() == QtCore.Qt.Key_C: #copy
                pass

    def mousePressEvent(self, e):
        #print e.x(), e.y()
        if e.button() == QtCore.Qt.RightButton:
            if self.counter % 2 == 0:
                text, ok = QtGui.QInputDialog.getText(self, 'Input Dialog', 
                                                        'Enter X1, Y1 (comma separated):')
                X1, Y1 = [float(v) for v in text.split(',')]
                if ok:
                    self.counter += 1
                    self.coord.setBottomPixelCoordinate(e.x(), e.y())
                    self.coord.setBottomGraphCoordinate(X1, Y1)


            else:
                text, ok = QtGui.QInputDialog.getText(self, 'Input Dialog', 
                                                        'Enter X2, Y2 (comma separated):')
                X2, Y2 = [float(v) for v in text.split(',')]
                if ok:
                    self.coord.setTopPixelCoordinate(e.x(), e.y())
                    self.coord.setTopGraphCoordinate(X2, Y2)
                    self.counter = 0

        elif e.button() == QtCore.Qt.LeftButton:
            try:
                x, y = self.coord.getGraphCoordinate(e.x(), e.y())
                print "%.5f %.5f" % (x, y)

            except AttributeError as e:
                print "please set the graph coordinate by right clicks."


    def displayImage(self, qimg):
        self.image_frame.setPixmap(QtGui.QPixmap.fromImage(qimg))

 
def main(args):
    app = QtGui.QApplication(sys.argv)
    form = MainWindow()
    form.show()
     
    sys.exit(app.exec_())
 
if __name__ == "__main__":
    main(sys.argv)


0 件のコメント:

コメントを投稿